# -*- coding: utf-8 -*-
# 请认准 VNPY官方网站 http://www.vnpy.cn
import webbrowser
import psutil as ps
import copy
import numpy as np
import pyqtgraph as pg
from PyQt5 import QtWidgets
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtWidgets import *
from PyQt5 import QtWidgets,QtGui,QtCore
from PyQt5.QtWidgets import QVBoxLayout, QWidget, QDialog, QPushButton, QMessageBox
import time
import os
import shutil
import configparser
from PyQt5.QtCore import *
import globalvar
import module_strategy
import module_strategyfilter
import module_talib
import module_instrumentgroup
import module_backtest
import module_dlg
# webview import module_backtestreport
import pandas as pd
import talib as ta
from module_strategybacktestprocess import *
from module_strategyprocess import *
import module_td
from datetime import timedelta
from datetime import datetime
import importlib
# 共享内存
import mmap
import threading

# K线图
global lasttime, kid
kid = 0
lasttime = -1.0

data_market = []
# pyqtgraph资金曲线图
data_backtest = []
# pyqtgraph实时资金曲线图
data_realtimecurve = []
# pyqtgraph K线
# 数据对应关系 (id, TradingDay, KlineTime,  open, close, min, ma).
data_kline = [(0, 0, 0, 0, 0, 0, 0), ]
count = 0


# 对话框
class DialogOptionsWidget(QWidget):
    def __init__(self, parent=None):
        super(DialogOptionsWidget, self).__init__(parent)

    def addCheckBox(self, text, value):
        pass


def setExistingDirectory(self):
    # options = QFileDialog.Options(QFlag(fileDialogOptionsWidget->value()))
    # options |= QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
    directory = QFileDialog.getExistingDirectory(self,
                                                 "QFileDialog.getExistingDirectory()",
                                                 self.label_directory.text())
    if directory:
        self.label_directory.setText(directory)

    # 打开文件对话框 取文件名


def setOpenFileName(self):
    # options = QFileDialog.Options(QFlag(fileDialogOptionsWidget.value()))
    # selectedFilter
    fileName, filetype = QFileDialog.getOpenFileName(self,
                                                     "QFileDialog.getOpenFileName()",
                                                     self.label_openFileName.text(),
                                                     "All Files (*);;Text Files (*.txt)")
    if fileName:
        self.label_openFileName.setText(fileName)

    # 打开文件对话框 取一组文件名


def setOpenFileNames(self):
    # options = QFileDialog.Options(QFlag(fileDialogOptionsWidget.value()))
    # selectedFilter
    openFilesPath = "D:/documents/pyMarksix/draw/"
    files, ok = QFileDialog.getOpenFileNames(self,
                                             "QFileDialog.getOpenFileNames()",
                                             openFilesPath,
                                             "All Files (*);;Text Files (*.txt)")

    if len(files):
        self.label_openFileNames.setText(", ".join(files))

    # 保存文件对话框 取文件名


def setsavefilename(self):
    # options = QFileDialog.Options(QFlag(fileDialogOptionsWidget.value()))
    # selectedFilter
    fileName, ok = QFileDialog.getSaveFileName(self,
                                               "QFileDialog.getSaveFileName()",
                                               self.label_saveFileName.text(),
                                               "All Files (*);;Text Files (*.txt)")
    if fileName:
        self.label_saveFileName.setText(fileName)


def criticalmessage(self):
    # reply = QMessageBox.StandardButton()
    MESSAGE = "批评！"
    reply = QMessageBox.critical(self,
                                 "QMessageBox.critical()",
                                 MESSAGE,
                                 QMessageBox.Abort | QMessageBox.Retry | QMessageBox.Ignore)
    if reply == QMessageBox.Abort:
        self.label_critical.setText("Abort")
    elif reply == QMessageBox.Retry:
        self.label_critical.setText("Retry")
    else:
        self.label_critical.setText("Ignore")


def informationmessage(self):
    MESSAGE = "信息"
    reply = QMessageBox.information(self, "QMessageBox.information()", MESSAGE)
    if reply == QMessageBox.Ok:
        self.label_information.setText("OK")
    else:
        self.label_information.setText("Escape")


def questionmessage(self):
    MESSAGE = "疑问"
    reply = QMessageBox.question(self, "QMessageBox.question()",
                                 MESSAGE,
                                 QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
    if reply == QMessageBox.Yes:
        self.label_question.setText("Yes")
    elif reply == QMessageBox.No:
        self.label_question.setText("No")
    else:
        self.label_question.setText("Cancel")


def warningmessage(self):
    MESSAGE = "警告文本"
    msgBox = QMessageBox(QMessageBox.Warning,
                         "QMessageBox.warning()",
                         MESSAGE,
                         QMessageBox.Retry | QMessageBox.Discard | QMessageBox.Cancel,
                         self)
    msgBox.setDetailedText("详细信息。。。")
    # msgBox.addButton("Save &Again", QMessageBox.AcceptRole)
    # msgBox.addButton("&Continue", QMessageBox.RejectRole)
    if msgBox.exec() == QMessageBox.AcceptRole:
        self.label_warning.setText("Retry")
    else:
        self.label_warning.setText("Abort")


def errormessage(self):
    self.errorMessageDialog.showMessage(
        "This dialog shows and remembers error messages. "
        "If the checkbox is checked (as it is by default), "
        "the shown message will be shown again, "
        "but if the user unchecks the box the message "
        "will not appear again if QErrorMessage.showMessage() "
        "is called with the same message.")
    self.label_error.setText("If the box is unchecked, the message "
                             "won't appear again.")


tradestate = 0

global markettj
markettj = 0
global config


class Ui_MainWindow(object):
    global markettj
    global lastTradingDay
    lastTradingDay = ''
    # 需要生成合约&周期的K线数据状态
    # 合约为dict,周期为list
    dict_instrument_period = {}
    dict_period = {'K线周期: M1': '1min', 'K线周期: M3': '3min',
                   'K线周期: M5': '5min', 'K线周期: M10': '10min',
                   'K线周期: M15': '15min', 'K线周期: M30': '30min',
                   'K线周期: M60': '60min', 'K线周期: M120': '120min',
                   'K线周期: D1': '1d'
                   }

    dict_period2 = {1: '1min', 3: '3min',
                    5: '5min', 10: '10min',
                    15: '15min', 30: '30min',
                    60: '60min', 120: '120min',
                    9999001: '1d'
                    }

    dict_period3 = {'K线周期: M1': 1, 'K线周期: M3': 3,
                    'K线周期: M5': 5, 'K线周期: M10': 10,
                    'K线周期: M15': 15, 'K线周期: M30': 30,
                    'K线周期: M60': 60, 'K线周期: M120': 120,
                    'K线周期: D1': 9999001
                    }

    dict_comboBox_kline_index = {1: 0, 3: 1,
                                 5: 2, 10: 3,
                                 15: 4, 30: 5,
                                 60: 6, 120: 7,
                                 9999001: 8
                                 }

    def update_depthMarketData(self, Price, InstrumentID):
        self.updatemarketUi(Price)
        self.updateklineUi(InstrumentID)

    def log_marketdata(self, mystr):
        global markettj
        markettj = markettj + 1
        if markettj > 14:
            self.list_marketdata.clear()
            markettj = 0
        _translate = QtCore.QCoreApplication.translate
        item = QtWidgets.QListWidgetItem()
        self.list_marketdata.addItem(item)
        item = self.list_marketdata.item(self.list_marketdata.count() - 1)
        tstr = time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime())
        item.setText(_translate("MainWindow", tstr + mystr))

    def callback_kline(self, msg):
        pass

    def callback_td_info(self, msg):
        # 将线程的参数传入
        pass

    def callback_md_tick(self, a):
        # 将线程的参数传入
        self.log_marketdata(str(a[0], encoding="utf-8") + "%.2f" % a[1])
        if globalvar.caompareinstrumwent(str(a[0], encoding="utf-8")):
            self.update_depthMarketData(a[1], a[0])

    def mounthyear4(self, thisdate, add):
        year = int(thisdate * 0.01)
        mounth = thisdate - year * 100
        mounth = mounth + add
        if mounth > 12:
            mounth = mounth - 12
            year = year + 1
        thisdate = year * 100 + mounth
        return thisdate

    def mounthyear3(self, thisdate, add):
        year = int(thisdate * 0.01)
        y = int(thisdate * 0.001)
        mounth = thisdate - year * 100
        mounth = mounth + add
        if mounth > 12:
            mounth = mounth - 12
            year = year + 1
        thisdate = year * 100 + mounth
        thisdate = thisdate - 1000 * y
        return thisdate

    def MakeInsutrumentID(self, instrumentMain, instrumentName, exchange, templist):
        global tempdate
        returnvalue = 0
        savedate = time.strftime("%Y%m%d", time.localtime())
        tvs = (int(float(savedate) * 0.000001)) * 1000000
        tempdate = int((float(savedate) - float(tvs)) * 0.01)
        tj = 0
        for j in range(12):
            if exchange == 'INE':
                returnvalue = self.mounthyear4(tempdate, j)
                if len(instrumentMain) > 0:
                    templist.append(instrumentMain + str(returnvalue))
            elif exchange == 'CFFEX':
                returnvalue = self.mounthyear4(tempdate, j)
                if len(instrumentMain) > 0:
                    templist.append(instrumentMain + str(returnvalue))
            elif exchange == 'SHFE':
                returnvalue = self.mounthyear4(tempdate, j)
                if len(instrumentMain) > 0:
                    templist.append(instrumentMain + str(returnvalue))
            elif exchange == 'DCE':
                returnvalue = self.mounthyear4(tempdate, j)
                if len(instrumentMain) > 0:
                    templist.append(instrumentMain + str(returnvalue))
            elif exchange == 'CZCE':
                returnvalue = self.mounthyear3(tempdate, j)
                if len(instrumentMain) > 0:
                    templist.append(instrumentMain + str(returnvalue))
        return returnvalue

    # 从服务器获取M1周期K线数据
    def GetKlineFromeServer(self):
        global data_kline, data_market
        self.plt_kline.clear()
        data_kline = [(0, 0, 0, 0, 0, 0, 0), ]
        globalvar.data_kline_M1.clear()
        data_market.clear()
        thisInstrument = str(globalvar.selectinstrumenid)
        try:
            # 清空该合约 DataFrame 数据
            if len(globalvar.dict_dataframe_kline_M1[thisInstrument]) > 0:
                globalvar.dict_dataframe_kline_M1[thisInstrument].drop(
                    globalvar.dict_dataframe_kline_M1[thisInstrument].index, inplace=True)
        except Exception as e:
            print("dict_dataframe_kline_M1 is empty: " + repr(e))
            globalvar.dict_dataframe_kline_M1[thisInstrument] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [], 'vol': []}, index=[])

        self.plt_kline.enableAutoRange(axis='y')
        self.plt_kline.setAutoVisible(y=False)
        # print('globalvar.thistoday: '+ str(globalvar.thistoday))
        # if globalvar.thistoday == 0:
        globalvar.thistoday = globalvar.vk.GetTradingDay()
        if globalvar.thistoday < 19000000:
            print("起始交易日错误" + str(globalvar.thistoday))
            return
        if globalvar.klineserverstate == 0:
            self.updateklineUi(globalvar.selectinstrumenid)
        elif globalvar.klineserverstate == 1:
            # 从服务器获取当日M1周期K线数据
            self.comboBox_kline.setCurrentIndex(self.dict_comboBox_kline_index[globalvar.selectperiod])
            # K线图切换到最后一次保存的周期，重新绘图
            self.ChangePeriodCharts_klineperiod(globalvar.selectperiod)
            globalvar.vk.GetServerKline(thisInstrument, int(globalvar.thistoday))
            self.UpdateKlineUIFromFile(globalvar.selectinstrumenid, int(globalvar.thistoday))
        elif globalvar.klineserverstate == 2:
            # 从服务器获取多日M1周期K线数据（需Plus会员）
            self.comboBox_kline.setCurrentIndex(self.dict_comboBox_kline_index[globalvar.selectperiod])
            # K线图切换到最后一次保存的周期，重新绘图
            self.ChangePeriodCharts_klineperiod(globalvar.selectperiod)
            if globalvar.vk.GetServerMultiKline(thisInstrument, int(globalvar.thistoday), 10,
                                                globalvar.Plus_UserName, globalvar.Plus_Password) == 1:
                self.UpdateMultiKlineUIFromFile(globalvar.selectinstrumenid, int(globalvar.thistoday))
                globalvar.PlusAuthState = 1
            else:
                webbrowser.open('http://www.vnpy.cn/qplus.html')

    # 从内存获取K线 M1周期数据
    def GetKlineFromeMemory(self, df, period_type):
        global data_kline, data_market
        self.plt_kline.clear()
        data_kline = [(0, 0, 0, 0, 0, 0, 0), ]
        globalvar.data_kline_M1.clear()
        data_market.clear()
        thisInstrument = str(globalvar.selectinstrumenid)
        self.plt_kline.enableAutoRange(axis='y')
        self.plt_kline.setAutoVisible(y=False)
        if globalvar.thistoday == 0:
            globalvar.thistoday = globalvar.vk.GetTradingDay()
        if globalvar.thistoday < 19000000:
            print("起始交易日错误" + str(globalvar.thistoday))
            return
        self.UpdateKlineChartsBycombox(globalvar.selectinstrumenid, period_type, df)

    # 由M1周期数据，通过DataFrame方式生成选中combox 周期的K线数据，并更新K线图表
    def UpdateKlineChartsBycombox(self, InstrumentID, period_type, df):
        global data_kline_M1
        data_kline_M1 = [(0, 0, 0, 0, 0, 0, 0), ]
        try:
            cid = 1
            globalvar.ticklist = []
            for index, row in df.iterrows():
                QApplication.processEvents()
                temp = (cid,
                        float(str(row['tradingday'])),
                        float(str(row['klinetime'])),
                        float(str(row['open'])),
                        float(str(row['close'])),
                        float(str(row['low'])),
                        float(str(row['high'])))
                globalvar.data_kline_M1.append(temp)

                tempstr = str(int(float(row['klinetime']) * 10000))
                tempstr_list = list(tempstr)
                tempstr_list.insert(len(tempstr_list) - 2, ':')
                tempstr = ''.join(tempstr_list)
                globalvar.ticklist.append(str(row['tradingday']) + "\n" + tempstr)

                cid = cid + 1
            self.plt_kline.removeItem(self.item)
            self.item = module_dlg.CandlestickItem(globalvar.data_kline_M1)  # 原始数据,对应（0,0）幅图
            try:
                self.plt_kline.addItem(self.item)
            except Exception as e:
                print("UpdateKlineChartsBycombox Error:" + repr(e))
            xax = self.plt_kline.getAxis('bottom')  # 坐标轴x
            xdict = dict(enumerate(globalvar.ticklist))
            xax.setTicks([xdict.items()])
        except Exception as e:
            print("UpdateKlineChartsBycombox Error:" + repr(e))

    def InitKlineDataFrame(self, InstrumentID):
        try:
            if isinstance(globalvar.dict_dataframe_kline_M3[InstrumentID], pd.DataFrame):
                pass
        except Exception as e:
            globalvar.dict_dataframe_kline_M3[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M5[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M10[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M15[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M30[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M60[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_M120[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            globalvar.dict_dataframe_kline_D1[InstrumentID] = pd.DataFrame(
                {'datetime': [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [], 'low': [], 'high': [],
                 'vol': []}, index=[])
            print("InitKlineDataFrame Error:" + repr(e))

    # DataFrame数据预处理，由M1周期数据，通过DataFrame方式生成选中combox 周期的K线数据，并更新K线图表
    # 根据M1 K线数据生成多个周期的K线数据，以DataFrame格式存储在dataframe_kline目录下
    def combineklineUpdateCharts(self, InstrumentID, period_type):
        # 初始化该合约DataFrame类型的除M1周期以外所有周期的K线数据变量
        self.InitKlineDataFrame(InstrumentID)
        dict_period_dataframe_kline = {'K线周期: M1': globalvar.dict_dataframe_kline_M1[InstrumentID],
                                       'K线周期: M3': globalvar.dict_dataframe_kline_M3[InstrumentID],
                                       'K线周期: M5': globalvar.dict_dataframe_kline_M5[InstrumentID],
                                       'K线周期: M10': globalvar.dict_dataframe_kline_M10[InstrumentID],
                                       'K线周期: M15': globalvar.dict_dataframe_kline_M15[InstrumentID],
                                       'K线周期: M30': globalvar.dict_dataframe_kline_M30[InstrumentID],
                                       'K线周期: M60': globalvar.dict_dataframe_kline_M60[InstrumentID],
                                       'K线周期: M120': globalvar.dict_dataframe_kline_M120[InstrumentID],
                                       'K线周期: D1': globalvar.dict_dataframe_kline_D1[InstrumentID]
                                       }
        try:

            if not os.path.exists(("dataframe_kline\\" + InstrumentID)):
                os.mkdir("dataframe_kline\\" + InstrumentID)
            globalvar.dict_dataframe_kline_M1[InstrumentID].to_csv(
                "dataframe_kline\\" + InstrumentID + "\\kline_1min.csv", index=False)
            data = pd.read_csv("dataframe_kline\\" + InstrumentID + "\\kline_1min.csv", index_col='datetime',
                               parse_dates=True)

            grouper = data.groupby(
                [pd.Grouper(freq=period_type), 'recordid', 'tradingday', 'klinetime', 'instrumentid', 'open', 'close',
                 'low', 'high',
                 'vol'])

            df = pd.DataFrame(grouper['instrumentid'].count())
            df.rename(columns={'instrumentid': 'count'}, inplace=True)
            df.reset_index(inplace=True)
            del df['count']

            df2 = pd.DataFrame(
                {"datetime": [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [],
                 'low': [], 'high': [],
                 'vol': []}, index=[])

            lastdatetime = ""
            high = 0
            low = 0
            open = 0
            close = 0
            vol = 0
            instrumentid = ""
            datetime = ""
            tradingday = ""
            klinetime = ""
            recordid = 1

            for index, row in df.iterrows():
                QApplication.processEvents()
                if lastdatetime != str(row['datetime']):
                    if open > 0:
                        tempdata = {"datetime": datetime, "recordid": '{:0>8s}'.format(str(recordid)),
                                    "tradingday": tradingday, "klinetime": klinetime,
                                    "instrumentid": instrumentid,
                                    "open": open, "close": close, "low": low, "high": high, "vol": vol}
                        df2 = df2.append(tempdata, ignore_index=True)
                    recordid = int(row['recordid'])
                    open = float(row['open'])
                    low = float(row['low'])
                    high = float(row['high'])
                    close = float(row['close'])
                    vol = int(row['vol'])
                    lastdatetime = str(row['datetime'])
                    lastclose = row['close']
                    datetime = row['datetime']
                    instrumentid = row['instrumentid']
                    tradingday = row['tradingday']
                    klinetime = row['klinetime']
                else:
                    recordid = int(row['recordid'])
                    low = min(low, float(row['low']))
                    high = max(high, float(row['high']))
                    close = float(row['close'])
                    vol = vol + int(row['vol'])

            df2 = df2.sort_values(by='recordid')
            df2.to_csv("dataframe_kline\\" + InstrumentID + "\\kline_" + period_type + ".csv", index=True)
            dict_period_dataframe_kline[period_type] = df2.copy()
            # 从内存获取K线数据并更新K线图表
            self.GetKlineFromeMemory(dict_period_dataframe_kline[period_type], period_type)
        except Exception as e:
            print("combineklineUpdateCharts Error:" + repr(e))

    # DataFrame数据预处理，由M1周期数据，后台方式计算，通过DataFrame方式生成选中combox 周期的K线数据，
    # 并根据M1 K线数据生成多个周期的K线数据，以DataFrame格式存储在dataframe_kline目录下
    def combineklineBackgroundCal(self, InstrumentID):
        # 初始化该合约DataFrame类型的除M1周期以外所有周期的K线数据变量
        self.InitKlineDataFrame(InstrumentID)
        dict_period_dataframe_kline = {'K线周期: M1': globalvar.dict_dataframe_kline_M1[InstrumentID],
                                       'K线周期: M3': globalvar.dict_dataframe_kline_M3[InstrumentID],
                                       'K线周期: M5': globalvar.dict_dataframe_kline_M5[InstrumentID],
                                       'K线周期: M10': globalvar.dict_dataframe_kline_M10[InstrumentID],
                                       'K线周期: M15': globalvar.dict_dataframe_kline_M15[InstrumentID],
                                       'K线周期: M30': globalvar.dict_dataframe_kline_M30[InstrumentID],
                                       'K线周期: M60': globalvar.dict_dataframe_kline_M60[InstrumentID],
                                       'K线周期: M120': globalvar.dict_dataframe_kline_M120[InstrumentID],
                                       'K线周期: D1': globalvar.dict_dataframe_kline_D1[InstrumentID]
                                       }
        try:
            if not os.path.exists(("dataframe_kline\\" + InstrumentID)):
                os.mkdir("dataframe_kline\\" + InstrumentID)
            globalvar.dict_dataframe_kline_M1[InstrumentID].to_csv(
                "dataframe_kline\\" + InstrumentID + "\\kline_1min.csv", index=False)
            data = pd.read_csv("dataframe_kline\\" + InstrumentID + "\\kline_1min.csv", index_col='datetime',
                               parse_dates=True)
            grouper = data.groupby(
                [pd.Grouper(freq=period_type), 'recordid', 'tradingday', 'klinetime', 'instrumentid', 'open', 'close',
                 'low', 'high',
                 'vol'])
            df = pd.DataFrame(grouper['instrumentid'].count())
            df.rename(columns={'instrumentid': 'count'}, inplace=True)
            df.reset_index(inplace=True)
            del df['count']
            df2 = pd.DataFrame(
                {"datetime": [], 'recordid': [], 'tradingday': [], 'klinetime': [], 'instrumentid': [], 'open': [],
                 'close': [],
                 'low': [], 'high': [],
                 'vol': []}, index=[])

            lastdatetime = ""
            high = 0
            low = 0
            open = 0
            close = 0
            vol = 0
            instrumentid = ""
            datetime = ""
            tradingday = ""
            klinetime = ""
            recordid = 1
            for index, row in df.iterrows():
                QApplication.processEvents()
                if lastdatetime != str(row['datetime']):
                    if open > 0:
                        tempdata = {"datetime": datetime, "recordid": '{:0>8s}'.format(str(recordid)),
                                    "tradingday": tradingday, "klinetime": klinetime,
                                    "instrumentid": instrumentid,
                                    "open": open, "close": close, "low": low, "high": high, "vol": vol}
                        df2 = df2.append(tempdata, ignore_index=True)
                    recordid = int(row['recordid'])
                    open = float(row['open'])
                    low = float(row['low'])
                    high = float(row['high'])
                    close = float(row['close'])
                    vol = int(row['vol'])
                    lastdatetime = str(row['datetime'])
                    lastclose = row['close']
                    datetime = row['datetime']
                    instrumentid = row['instrumentid']
                    tradingday = row['tradingday']
                    klinetime = row['klinetime']
                else:
                    recordid = int(row['recordid'])
                    low = min(low, float(row['low']))
                    high = max(high, float(row['high']))
                    close = float(row['close'])
                    vol = vol + int(row['vol'])

            df2 = df2.sort_values(by='recordid')
            df2.to_csv("dataframe_kline\\" + InstrumentID + "\\kline_" + period_type + ".csv", index=True)
            dict_period_dataframe_kline[period_type] = df2.copy()
        except Exception as e:
            print("combineklineBackgroundCal Error:" + repr(e))

    def to_comboBox_klineperiod(self, text):
        globalvar.selectperiod = self.dict_period3[text]
        print('globalvar.selectperiod: ' + str(globalvar.selectperiod))
        print('globalvar.selectinstrumenid: ' + str(globalvar.selectinstrumenid))
        print('self.dict_period[text]: ' + str(self.dict_period[text]))
        self.combineklineUpdateCharts(globalvar.selectinstrumenid, self.dict_period[text])

    def ChangePeriodCharts_klineperiod(self, period):
        self.combineklineUpdateCharts(globalvar.selectinstrumenid, self.dict_period2[period])

    def Background_klineperiod(self):
        self.combineklineBackgroundCal(globalvar.selectinstrumenid)

    def to_comboBox_1(self, text):
        self.comboBox_instrument.clear()
        self.comboBox_instrumentid.clear()
        templist = text.split(",", -1)
        if templist[0] == 'ALL':
            self.comboBox_instrument.addItems(globalvar.list_INE)
            self.comboBox_instrument.addItems(globalvar.list_CFFEX)
            self.comboBox_instrument.addItems(globalvar.list_SHFE)
            self.comboBox_instrument.addItems(globalvar.list_DCE)
            self.comboBox_instrument.addItems(globalvar.list_CZCE)
        elif templist[0] == 'INE':
            self.comboBox_instrument.addItems(globalvar.list_INE)
            if len(globalvar.list_INE) > 0:
                templist2 = globalvar.list_INE[0].split(",", -1)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
                self.comboBox_instrumentid.clear()
                templist = globalvar.list_INE[0].split(",", -1)
                templist2 = []
                self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
                self.comboBox_instrumentid.addItems(templist2)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
        elif templist[0] == 'CFFEX':
            self.comboBox_instrument.addItems(globalvar.list_CFFEX)
            if len(globalvar.list_CFFEX) > 0:
                templist2 = globalvar.list_CFFEX[0].split(",", -1)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
                self.comboBox_instrumentid.clear()
                templist = globalvar.list_CFFEX[0].split(",", -1)
                templist2 = []
                self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
                self.comboBox_instrumentid.addItems(templist2)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
        elif templist[0] == 'SHFE':
            self.comboBox_instrument.addItems(globalvar.list_SHFE)
            if len(globalvar.list_SHFE) > 0:
                templist2 = globalvar.list_SHFE[0].split(",", -1)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
                self.comboBox_instrumentid.clear()
                templist = globalvar.list_SHFE[0].split(",", -1)
                templist2 = []
                self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
                self.comboBox_instrumentid.addItems(templist2)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
        elif templist[0] == 'DCE':
            self.comboBox_instrument.addItems(globalvar.list_DCE)
            if len(globalvar.list_DCE) > 0:
                templist2 = globalvar.list_DCE[0].split(",", -1)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
                self.comboBox_instrumentid.clear()
                templist = globalvar.list_DCE[0].split(",", -1)
                templist2 = []
                self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
                self.comboBox_instrumentid.addItems(templist2)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
        elif templist[0] == 'CZCE':
            self.comboBox_instrument.addItems(globalvar.list_CZCE)
            if len(globalvar.list_CZCE) > 0:
                templist2 = globalvar.list_CZCE[0].split(",", -1)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
                self.comboBox_instrumentid.clear()
                templist = globalvar.list_CZCE[0].split(",", -1)
                templist2 = []
                self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
                self.comboBox_instrumentid.addItems(templist2)
                globalvar.selectinstrumenid = templist2[0]
                globalvar.rc.updatehistorystock(templist2[0])
        self.GetKlineFromeServer()

    def to_comboBox_2(self, text):
        self.comboBox_instrumentid.clear()
        templist = text.split(",", -1)
        templist2 = []
        self.MakeInsutrumentID(templist[0], templist[1], templist[2], templist2)
        self.comboBox_instrumentid.addItems(templist2)
        globalvar.selectinstrumenid = templist2[0]
        globalvar.rc.updatehistorystock(templist2[0])
        if templist[2] == 'ALL':
            self.comboBox_exchange.setCurrentText(templist[2] + ',全部交易所')
            globalvar.selectexchange = templist[2]
        elif templist[2] == 'INE':
            self.comboBox_exchange.setCurrentText(templist[2] + ',能源所')
            globalvar.selectexchange = templist[2]
        elif templist[2] == 'CFFEX':
            self.comboBox_exchange.setCurrentText(templist[2] + ',中金所')
            globalvar.selectexchange = templist[2]
        elif templist[2] == 'SHFE':
            self.comboBox_exchange.setCurrentText(templist[2] + ',上期所')
            globalvar.selectexchange = templist[2]
        elif templist[2] == 'DCE':
            self.comboBox_exchange.setCurrentText(templist[2] + ',大商所')
            globalvar.selectexchange = templist[2]
        elif templist[2] == 'CZCE':
            self.comboBox_exchange.setCurrentText(templist[2] + ',郑商所')
            globalvar.selectexchange = templist[2]
        self.GetKlineFromeServer()

    def to_comboBox_3(self, text):
        globalvar.selectinstrumenid = text
        globalvar.rc.updatehistorystock(text)
        self.GetKlineFromeServer()

    def change_comboBox(self, text):
        global dict_instrument, dict_instrument
        globalvar.rc.updatehistorystock(text)
        if text in globalvar.dict_exchange:
            self.comboBox_exchange.setCurrentText(str(globalvar.dict_exchange[text]))
            self.to_comboBox_1(str(globalvar.dict_exchange[text]))
            self.comboBox_instrument.setCurrentText(str(globalvar.dict_instrument[text]))
            self.to_comboBox_2(str(globalvar.dict_instrument[text]))
            self.comboBox_instrumentid.setCurrentText(text)
            self.to_comboBox_3(text)

    def callback_md_combox(self):
        self.comboBox_instrument.addItems(globalvar.list_INE)
        self.comboBox_instrument.addItems(globalvar.list_CFFEX)
        self.comboBox_instrument.addItems(globalvar.list_SHFE)
        self.comboBox_instrument.addItems(globalvar.list_DCE)
        self.comboBox_instrument.addItems(globalvar.list_CZCE)

    def move_button(self):
        pass

    def OnStart(self):
        if globalvar.backteststate == 0:
            globalvar.tradestate = 1
            self.SetBarRunState(globalvar.tradestate)
            self.Button_Start.setEnabled(False)
            self.Button_Stop.setEnabled(True)
            self.Button_Start.setStyleSheet("QPushButton{border-image: url(onstart2.png)}")
            self.Button_Stop.setStyleSheet("QPushButton{border-image: url(onstop1.png)}")
        else:
            self.autologoutwarnwin = QMessageBox(None)
            self.autologoutwarnwin.setIcon(QMessageBox.Warning)
            self.autologoutwarnwin.setText(('请先停止回测，再开启程序化交易！'))
            self.autologoutwarnwin.setWindowTitle(('说明'))
            self.autologoutwarnwin.setStandardButtons(QMessageBox.Ok)
            self.autologoutwarnwin.exec_()

    def OnStop(self):
        print('OnStop')
        globalvar.tradestate = 0
        self.SetBarRunState(globalvar.tradestate)
        self.Button_Start.setEnabled(True)
        self.Button_Stop.setEnabled(False)
        self.Button_Start.setStyleSheet("QPushButton{border-image: url(onstart1.png)}")
        self.Button_Stop.setStyleSheet("QPushButton{border-image: url(onstop2.png)}")

    def ClearPath(self, path, suffix):
        ls = os.listdir(path)
        for i in ls:
            c_path = os.path.join(path, i)
            if os.path.isdir(c_path):
                print(c_path)
                self.ClearPath(c_path, suffix)
            else:
                file = os.path.splitext(c_path)
                filename, type = file
                if '说明' in filename:
                    return
                elif type == suffix:
                    os.remove(c_path)
                    print("Delete file complete :", c_path)

    def Function_ClearMdLog(self):
        self.ClearPath("logfile/md", ".txt")
        self.table_historymd.clear()
        self.table_historymd.setRowCount(0)
        self.table_historymd.setHorizontalHeaderLabels(['ID', '文件（文件名为日期，双击打开日志）', '操作'])

    def Function_ClearTdLog(self):
        self.ClearPath("logfile/td", ".txt")
        self.table_historytd.clear()
        self.table_historytd.setRowCount(0)
        self.table_historytd.setHorizontalHeaderLabels(['ID', '文件（文件名为日期，双击打开日志）', '操作'])

    # 打开资金曲线对话框
    def Function_OpenCapitalCurve(self):
        ui_demo = module_dlg.DialogCapitalCurve()
        ui_demo.centralWidget()
        screen = QDesktopWidget().screenGeometry()
        size = ui_demo.geometry()
        ui_demo.move((screen.width() - size.width()) / 2,
                     (screen.height() - size.height()) / 2)
        ui_demo.setWindowTitle('添加交易账户')
        ui_demo.show()
        ui_demo.resize(450, 300)
        ui_demo.exec_()

    # 策略说明
    def Function_StrategyInstructions(self):
        webbrowser.open('https://zhuanlan.zhihu.com/p/393090084')

    # 添加合约组
    def Function_AddInstrumentGroup(self):
        webbrowser.open('https://zhuanlan.zhihu.com/p/393090084')

    # 关于合约组
    def Function_AboutInstrumentGroup(self):
        webbrowser.open('https://zhuanlan.zhihu.com/p/393090084')

    # 双击下单
    def Function_doubleClicked_TradeConfirm(self):
        ui_demo = module_dlg.DialogTradeConfirm()
        screen = QDesktopWidget().screenGeometry()
        size = ui_demo.geometry()
        ui_demo.move((screen.width() - size.width()) / 2,
                     (screen.height() - size.height()) / 2)
        ui_demo.setWindowTitle('下单确认')
        ui_demo.show()
        ui_demo.resize(600, 440)
        ui_demo.exec_()

    # 添加账户
    def Function_AddInvestor(self):
        ui_demo = module_dlg.DialogInvestor()
        screen = QDesktopWidget().screenGeometry()
        size = ui_demo.geometry()
        ui_demo.move((screen.width() - size.width()) / 2,
                     (screen.height() - size.height()) / 2)
        ui_demo.setWindowTitle('添加交易账户')
        ui_demo.show()
        ui_demo.resize(600, 440)
        ui_demo.exec_()

    # 修改账户
    def Function_ModifyInvestor(self):
        webbrowser.open('https://zhuanlan.zhihu.com/p/382856586')
        '''
        ui_demo = module_dlg.DialogInvestor()
        # 居中窗口
        screen = QDesktopWidget().screenGeometry()
        size = ui_demo.geometry()
        ui_demo.move((screen.width() - size.width()) / 2 -75,
                  (screen.height() - size.height()) / 2  -50)
        ui_demo.setWindowTitle('修改交易账户')
        ui_demo.show()
        ui_demo.resize(450, 300)
        self.childwidget = self.childwidget(self)
        self.childwidget.exec_()
        '''

    def Function_OpenLog_TD(self):
        pass
        return
        '''
        import subprocess as sp
        programName = "notepad.exe"
        fileName = "log//td//" + '2021' + ".txt"
        sp.Popen([programName, fileName])
        '''

    def Function_OpenLog_MD(self):
        pass
        return
        '''
        import subprocess as sp
        programName = "notepad.exe"
        fileName = "log//md//" + '2021' + ".txt"
        sp.Popen([programName, fileName])
        '''

    def Function_OpenUrl_SIMNOW(self):
        # QtWidgets.QMessageBox.warning(self, "Warning", "输入数据错误，请重新输入！",QMessageBox.Yes)
        self.autologoutwarnwin = QMessageBox(None)
        self.autologoutwarnwin.setIcon(QMessageBox.Warning)
        self.autologoutwarnwin.setText(('上期SIMNOW官网提供CTP模拟账户注册，\n网站只能在工作日白天才能访问。\n\n但模拟交易账户注册成功后，\n和实盘账户交易时间是一致的。'))
        self.autologoutwarnwin.setWindowTitle(('说明'))
        self.autologoutwarnwin.setStandardButtons(QMessageBox.Ok)
        self.buttonOK = self.autologoutwarnwin.button(QMessageBox.Ok)
        self.buttonOK.setText('我知道了,打开上期SIMNOW网站')
        # self.autologoutwarnwin.buttonClicked.connect(self.autologoutwarn_accepted)
        self.autologoutwarnwin.exec_()
        webbrowser.open('http://www.simnow.com.cn/')

    def Function_OpenUrl_VNPY(self):
        webbrowser.open('http://www.vnpy.cn/')

    def Function_OpenUrl_VNTRADER(self):
        webbrowser.open('http://www.vntrader.cn/')

    def Function_OpenUrl_ZHIHU(self):
        webbrowser.open('https://www.zhihu.com/org/vnpy/posts')

    def Function_OpenUrl_ZHIHUVIDEO(self):
        webbrowser.open('https://www.zhihu.com/org/vnpy/zvideos/')

    def Function_OpenUrl_COOLQUANT(self):
        webbrowser.open('http://www.coolquant.cn/')

    def Function_OpenUrl_KAIHU(self):
        webbrowser.open('http://www.kaihucn.cn/')

    def Function_OpenUrl_Plus(self):
        webbrowser.open('http://www.vnpy.cn/qplus.html')

    def Function_OpenUrl_Community(self):
        webbrowser.open('http://q.vnpy.cn/')

    def Function_OpenUrl_BandPlus(self):
        webbrowser.open('http://q.vnpy.cn/')

    def Function_OpenUrl_Buyplus(self):
        webbrowser.open('http://q.vnpy.cn/')

    def Function_FaqKAIHU(self):
        webbrowser.open('https://www.zhihu.com/zvideo/1333746770867236864')

    def Function_OpenDllLog(self):
        self.Button_OpenDll.setChecked(True)
        self.Button_CloseDll.setChecked(False)
        global td, md
        globalvar.md.OpenLog()
        globalvar.td.OpenLog()

    def Function_CloseDllLog(self):
        self.Button_OpenDll.setChecked(False)
        self.Button_CloseDll.setChecked(True)
        global td, md
        globalvar.md.CloseLog()
        globalvar.td.CloseLog()

    def Function_EnableStrategyManage_SingleThread(self):
        self.Button_StrategyManage_SingleThread.setChecked(True)
        self.Button_StrategyManage_MulitProcess.setChecked(False)

    def Function_EnableStrategyManage_MulitProcess(self):
        self.Button_StrategyManage_SingleThread.setChecked(True)
        self.Button_StrategyManage_MulitProcess.setChecked(False)

    def Function_KlineSource_RealTimeTick(self):
        self.Button_KlineSource_RealTimeTick.setChecked(True)
        self.Button_KlineSource_ServerToday.setChecked(False)
        self.Button_KlineSource_ServerMultiday.setChecked(False)
        globalvar.klineserverstate = 0

    def Function_KlineSource_ServerToday(self):
        self.Button_KlineSource_RealTimeTick.setChecked(False)
        self.Button_KlineSource_ServerToday.setChecked(True)
        self.Button_KlineSource_ServerMultiday.setChecked(False)
        globalvar.klineserverstate = 1
        self.GetKlineFromeServer()

    def Function_KlineSource_ServerMultiday(self):
        self.Button_KlineSource_RealTimeTick.setChecked(False)
        self.Button_KlineSource_ServerToday.setChecked(False)
        self.Button_KlineSource_ServerMultiday.setChecked(True)
        globalvar.klineserverstate = 2
        self.GetKlineFromeServer()

    def Function_FaqDevelopmentEnvironment(self):
        webbrowser.open('https://www.zhihu.com/zvideo/1333746770867236864')

    def Function_doubleClicked_algorithmtrading_limit(self):
        """
         作用：双击事件监听，显示被选中的单元格
        """
        # 打印被选中的单元格
        for i in self.table_algorithmtrading.selectedItems():
            print(i.row(), i.column(), i.text())
            # self.setWindowTitle(i.text())

    def Function_doubleClicked_Trade(self):
        """
         作用：双击事件监听，显示被选中的单元格
        """
        # 打印被选中的单元格
        for i in self.table_account.selectedItems():
            print(i.row(), i.column(), i.text())
            # self.setWindowTitle(i.text())

    def Function_doubleClicked_strategy(self):
        for i in self.table_strategy.selectedItems():
            # print(i.row(), i.column(), i.text())
            print(i.text())
            os.system(i.text())

    # 双击打开历史交易日志
    def Function_doubleClicked_historytd(self):
        """
        作用：双击事件监听，用默认方式打开文件
        """
        for i in self.table_historytd.selectedItems():
            # print(i.row(), i.column(), i.text())
            print(i.text())
            os.system(i.text())

    # 双击打开历史行情日志
    def Function_doubleClicked_historymd(self):
        """
        作用：双击事件监听，用默认方式打开文件
        """
        for i in self.table_historymd.selectedItems():
            # print(i.row(), i.column(), i.text())
            print(i.text())
            os.system(i.text())

    def Function_Buttonclickh1(self):
        try:
            if '最近访问' in self.Button_h[0].text():
                return
            else:
                self.change_comboBox(self.Button_h[0].text())
        except Exception as e:
            print("Function_Buttonclickh1:" + repr(e))

    def Function_Buttonclickh2(self):
        try:
            if '最近访问' in self.Button_h[1].text():
                return
            else:
                self.change_comboBox(self.Button_h[1].text())
        except Exception as e:
            print("Function_Buttonclickh2:" + repr(e))

    def Function_Buttonclickh3(self):
        try:
            if '最近访问' in self.Button_h[2].text():
                return
            else:
                self.change_comboBox(self.Button_h[2].text())
        except Exception as e:
            print("Function_Buttonclickh3:" + repr(e))

    def Function_Buttonclickh4(self):
        try:
            if '最近访问' in self.Button_h[3].text():
                return
            else:
                self.change_comboBox(self.Button_h[3].text())
        except Exception as e:
            print("Function_Buttonclickh4:" + repr(e))

    def Function_Buttonclickh5(self):
        try:
            if '最近访问' in self.Button_h[4].text():
                return
            else:
                self.change_comboBox(self.Button_h[4].text())
        except Exception as e:
            print("Function_Buttonclickh5:" + repr(e))

    def Function_Buttonclickh6(self):
        try:
            if '最近访问' in self.Button_h[5].text():
                return
            else:
                self.change_comboBox(self.Button_h[5].text())
        except Exception as e:
            print("Function_Buttonclickh6:" + repr(e))

    def Function_Buttonclickh7(self):
        try:
            if '最近访问' in self.Button_h[6].text():
                return
            else:
                self.change_comboBox(self.Button_h[6].text())
        except Exception as e:
            print("Function_Buttonclickh7:" + repr(e))

    def Function_Buttonclickh8(self):
        try:
            if '最近访问' in self.Button_h[7].text():
                return
            else:
                self.change_comboBox(self.Button_h[7].text())
        except Exception as e:
            print("Function_Buttonclickh8:" + repr(e))

    def Function_Buttonclickt1(self):
        try:
            if '最近交易' in self.Button_t[0].text():
                return
            else:
                self.change_comboBox(self.Button_t[0].text())
        except Exception as e:
            print("Function_Buttonclickt1:" + repr(e))

    def Function_Buttonclickt2(self):
        try:
            if '最近交易' in self.Button_t[1].text():
                return
            else:
                self.change_comboBox(self.Button_t[1].text())
        except Exception as e:
            print("Function_Buttonclickt2:" + repr(e))

    def Function_Buttonclickt3(self):
        try:
            if '最近交易' in self.Button_t[2].text():
                return
            else:
                self.change_comboBox(self.Button_t[2].text())
        except Exception as e:
            print("Function_Buttonclickt3:" + repr(e))

    def Function_Buttonclickt4(self):
        try:
            if '最近交易' in self.Button_t[3].text():
                return
            else:
                self.change_comboBox(self.Button_t[3].text())
        except Exception as e:
            print("Function_Buttonclickt4:" + repr(e))

    def Function_Buttonclickt5(self):
        try:
            if '最近交易' in self.Button_t[4].text():
                return
            else:
                self.change_comboBox(self.Button_t[4].text())
        except Exception as e:
            print("Function_Buttonclickt5:" + repr(e))

    def Function_Buttonclickt6(self):
        try:
            if '最近交易' in self.Button_t[5].text():
                return
            else:
                self.change_comboBox(self.Button_t[5].text())
        except Exception as e:
            print("Function_Buttonclickt6:" + repr(e))

    def Function_Buttonclickt7(self):
        try:
            if '最近交易' in self.Button_t[6].text():
                return
            else:
                self.change_comboBox(self.Button_t[6].text())
        except Exception as e:
            print("Function_Buttonclickt7:" + repr(e))

    def Function_Buttonclickt8(self):
        try:
            if '最近交易' in self.Button_t[7].text():
                return
            else:
                self.change_comboBox(self.Button_t[7].text())
        except Exception as e:
            print("Function_Buttonclickt8:" + repr(e))

    def Function_Buttonclickz1(self):
        try:
            if '自选' in self.Button_zx[0].text():
                return
            else:
                self.change_comboBox(self.Button_zx[0].text())
        except Exception as e:
            print("Function_Buttonclickz1:" + repr(e))

    def Function_Buttonclickz2(self):
        try:
            if '自选' in self.Button_zx[1].text():
                return
            else:
                self.change_comboBox(self.Button_zx[1].text())
        except Exception as e:
            print("Function_Buttonclickz2:" + repr(e))

    def Function_Buttonclickz3(self):
        try:
            if '自选' in self.Button_zx[2].text():
                return
            else:
                self.change_comboBox(self.Button_zx[2].text())
        except Exception as e:
            print("Function_Buttonclickz3:" + repr(e))

    def Function_Buttonclickz4(self):
        try:
            if '自选' in self.Button_zx[3].text():
                return
            else:
                self.change_comboBox(self.Button_zx[3].text())
        except Exception as e:
            print("Function_Buttonclickz4:" + repr(e))

    def Function_Buttonclickz5(self):
        try:
            if '自选' in self.Button_zx[4].text():
                return
            else:
                self.change_comboBox(self.Button_zx[4].text())
        except Exception as e:
            print("Function_Buttonclickz5:" + repr(e))

    def Function_Buttonclickz6(self):
        try:
            if '自选' in self.Button_zx[5].text():
                return
            else:
                self.change_comboBox(self.Button_zx[5].text())
        except Exception as e:
            print("Function_Buttonclickz6:" + repr(e))

    def Function_Buttonclickz7(self):
        try:
            if '自选' in self.Button_zx[6].text():
                return
            else:
                self.change_comboBox(self.Button_zx[6].text())
        except Exception as e:
            print("Function_Buttonclickz7:" + repr(e))

    def Function_Buttonclickz8(self):
        try:
            if '自选' in self.Button_zx[7].text():
                return
            else:
                self.change_comboBox(self.Button_zx[7].text())
        except Exception as e:
            print("Function_Buttonclickz8:" + repr(e))

    def InitReadTalibcondition(self):
        with open("talib.csv", "r") as f:
            for line in f.readlines():
                line = line.strip('\n')
                strlist = line.split(",")
                try:
                    if len(globalvar.dict_talibcondition[strlist[0]]) == 0:
                        pass
                except Exception as e:
                    globalvar.dict_talibcondition[strlist[0]] = []
                    print("Function_Buttonclicke0 Error:" + repr(e))
                globalvar.dict_talibcondition[strlist[0]].append(strlist)

    def InitReadTalibconditionIni(self):
        import configparser
        conf = configparser.ConfigParser()
        conf.read("./talib.ini")
        sections = conf.sections()
        # 给字典增加key
        for i, j in enumerate(sections):
            # globalvar.dict_talibcondition[i]=[]
            options = conf.options(j)
            globalvar.dict_talibcondition[j] = []
            for m, n in enumerate(options):
                # globalvar.dict_talibcondition[j][m]= conf.get(j, n)
                globalvar.dict_talibcondition[j].append(conf.get(j, n))

    def SetBarRunState(self, state):
        if state == 0:
            self.lab_run.setPixmap(QPixmap('ico/ico_alert_stop.png'))
        elif state == 1:
            self.lab_run.setPixmap(QPixmap('ico/ico_alert_run.png'))

    def SetBarMDState(self, state):
        if state == 1:
            self.lab_md.setPixmap(QPixmap('ico/ico_error_mdconnect.png'))
        elif state == 2:
            self.lab_md.setPixmap(QPixmap('ico/ico_right_mdlogin.png'))
        elif state == 3:
            self.lab_md.setPixmap(QPixmap('ico/ico_right_mdlogin.png'))

    def SetBarTDState(self, state):
        if state == 1:
            self.lab_td.setPixmap(QPixmap('ico/ico_error_tdconnect.png'))
        elif state == 2:
            self.lab_td.setPixmap(QPixmap('ico/ico_right_tdlogin.png'))
        elif state == 3:
            self.lab_td.setPixmap(QPixmap('ico/ico_right_tdlogin.png'))

    def move_center(self, Q):
        screen = QDesktopWidget().screenGeometry()
        form = Q.geometry()
        x_move_step = (screen.width() - form.width()) / 2
        y_move_step = (screen.height() - form.height()) / 2
        Q.move(x_move_step, y_move_step)

    def setupUi(self, MainWindow):
        self.MainWindow = MainWindow
        self.MainWindow.setObjectName("MainWindow")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setTabPosition(QtWidgets.QTabWidget.East)
        self.tabWidget.setTabsClosable(False)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.gridLayout = QtWidgets.QGridLayout(self.tab)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QtWidgets.QGroupBox(self.tab)
        self.groupBox.setObjectName("groupBox")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.toolBox1 = QtWidgets.QToolBox(self.groupBox)

        # 组标题 toolBox1
        self.toolBox1.setObjectName("")
        self.page_order = QtWidgets.QWidget()
        self.page_order.setGeometry(QtCore.QRect(0, 0, 98, 44))
        self.page_order.setObjectName("page_order")
        self.gridLayout_instrument = QtWidgets.QGridLayout(self.page_order)
        self.gridLayout_instrument.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_instrument.setObjectName("gridLayout_instrument")
        self.table_order = QtWidgets.QTableWidget(self.page_order)
        self.table_order.setObjectName("table_Order")
        self.table_order.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_order.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_order.setEditTriggers(QTableView.NoEditTriggers)
        self.table_order.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_order.setColumnCount(11)
        self.table_order.setRowCount(0)
        self.table_order.setHorizontalHeaderLabels(
            ['报单编号', '合约', '买卖', '开平', '报单状态', '价格', '报单数', '已成交', '未成交', '报单时间', '交易所'])
        self.table_order.setSortingEnabled(True)  # 设置表头可以自动排序

        self.gridLayout_instrument.addWidget(self.table_order, 0, 0, 1, 1)
        self.toolBox1.addItem(self.page_order, "")
        self.page_instrument = QtWidgets.QWidget()
        self.page_instrument.setGeometry(QtCore.QRect(0, 0, 98, 44))
        self.page_instrument.setObjectName("page_instrument")
        self.gridLayout_instrument = QtWidgets.QGridLayout(self.page_instrument)
        self.gridLayout_instrument.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_instrument.setObjectName("gridLayout_instrument")

        self.table_instrumentcx = QtWidgets.QTableWidget(self.page_instrument)
        self.table_instrumentcx.setObjectName("table_Order")
        self.table_instrumentcx.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_instrumentcx.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_instrumentcx.setEditTriggers(QTableView.NoEditTriggers)
        self.table_instrumentcx.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_instrumentcx.setColumnCount(8)
        self.table_instrumentcx.setRowCount(4)
        self.table_instrumentcx.setHorizontalHeaderLabels(
            ['品种代码', '合约', '合约名', '交易所', '合约乘数', '最小价格变动单位', '保证金', '手续费'])
        # 下方表格
        self.table_instrumentcx.setColumnWidth(0, 120)
        self.table_instrumentcx.setColumnWidth(1, 120)
        self.table_instrumentcx.setColumnWidth(2, 120)
        self.table_instrumentcx.setColumnWidth(3, 120)
        self.table_instrumentcx.setColumnWidth(4, 120)
        self.table_instrumentcx.setColumnWidth(5, 120)
        self.table_instrumentcx.setColumnWidth(6, 120)
        self.table_instrumentcx.setColumnWidth(7, 120)
        self.table_instrumentcx.setSortingEnabled(True)  # 设置表头可以自动排序
        self.gridLayout_instrument.addWidget(self.table_instrumentcx, 0, 0, 1, 1)
        self.page_trade = QtWidgets.QWidget()
        self.page_trade.setGeometry(QtCore.QRect(0, 0, 697, 210))
        self.page_trade.setObjectName("page_trade")
        self.gridLayout_position = QtWidgets.QGridLayout(self.page_trade)
        self.gridLayout_position.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_position.setObjectName("gridLayout_position")

        self.table_trade = QtWidgets.QTableWidget(self.page_trade)
        self.table_trade.setObjectName("table_trade")
        self.table_trade.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_trade.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_trade.setEditTriggers(QTableView.NoEditTriggers)
        self.table_trade.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_trade.doubleClicked.connect(self.Function_doubleClicked_Trade)
        self.table_trade.setColumnCount(11)
        self.table_trade.setRowCount(0)
        self.table_trade.setHorizontalHeaderLabels(
            ['策略名称', '成交编号', '报单编号', '合约', '买卖', '开平', '成交价格', '数量', '成交类型', '成交时间', '交易所'])
        self.table_trade.setSortingEnabled(True)  # 设置表头可以自动排序
        self.gridLayout_position.addWidget(self.table_trade, 1, 1, 1, 1)

        self.page_position = QtWidgets.QWidget()
        self.page_position.setGeometry(QtCore.QRect(0, 0, 697, 210))
        self.page_position.setObjectName("page_position")
        self.gridLayout_position = QtWidgets.QGridLayout(self.page_position)
        self.gridLayout_position.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_position.setObjectName("gridLayout_position")
        self.table_position = QtWidgets.QTableWidget(self.page_trade)
        self.table_position.setObjectName("table_trade")
        self.table_position.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_position.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_position.setEditTriggers(QTableView.NoEditTriggers)
        self.table_position.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_position.setColumnCount(8)
        self.table_position.setRowCount(0)
        self.table_position.setHorizontalHeaderLabels(
            ['合约', '买卖', '总持仓', '今仓', '可平量', '占用保证金', '持仓成本', '持仓盈亏'])
        # 设置行高
        self.table_position.setRowHeight(0, 30)
        self.table_position.setSortingEnabled(True)  # 设置表头可以自动排序
        self.table_position.horizontalHeader().setStretchLastSection(True)  ##设置最后一列拉伸至最大
        self.table_position.doubleClicked.connect(self.Function_doubleClicked_algorithmtrading_limit)

        self.gridLayout_position.addWidget(self.table_position, 1, 1, 1, 1)
        self.toolBox1.addItem(self.page_trade, "")

        self.verticalLayout_3.addWidget(self.toolBox1)
        self.toolBox1.addItem(self.page_position, "")
        self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1)
        self.tabWidget_2 = QtWidgets.QTabWidget(self.tab)
        self.tabWidget_2.setObjectName("tabWidget_2")

        self.tab_strategy = QtWidgets.QWidget()
        self.tab_strategy.setObjectName("tab_strategy")
        self.tab_instrumentgroup = QtWidgets.QWidget()
        self.tab_instrumentgroup.setObjectName("tab_instrumentgroup")
        self.tab_account = QtWidgets.QWidget()
        self.tab_account.setObjectName("tab_account")
        self.tab_plus = QtWidgets.QWidget()
        self.tab_plus.setObjectName("tab_plus")
        self.tab_marketdata = QtWidgets.QWidget()
        self.tab_marketdata.setObjectName("tab_marketdata")
        self.tab_instrument = QtWidgets.QWidget()
        self.tab_instrument.setObjectName("tab_instrument")
        self.tab_algorithmtrading = QtWidgets.QWidget()
        self.tab_algorithmtrading.setObjectName("tab_algorithmtrading")
        self.tab_listtdlog = QtWidgets.QWidget()
        self.tab_listtdlog.setObjectName("tab_listtdlog")
        self.tab_listmdlog = QtWidgets.QWidget()
        self.tab_listmdlog.setObjectName("tab_listmdlog")
        self.tab_historytd = QtWidgets.QWidget()
        self.tab_historytd.setObjectName("tab_historytd")
        self.tab_historymd = QtWidgets.QWidget()
        self.tab_historymd.setObjectName("tab_historymd")
        self.tab_backtestdata = QtWidgets.QWidget()
        self.tab_backtestdata.setObjectName("tab_backtestdata")
        self.tab_result = QtWidgets.QWidget()
        self.tab_result.setObjectName("tab_result")

        self.tab_faq = QtWidgets.QWidget()
        self.tab_faq.setObjectName("tab_faq")
        self.tabWidget_2.addTab(self.tab_strategy, "")
        self.tabWidget_2.addTab(self.tab_instrumentgroup, "")
        self.tabWidget_2.addTab(self.tab_account, "")
        self.tabWidget_2.addTab(self.tab_plus, "")
        self.tabWidget_2.addTab(self.tab_marketdata, "")
        self.tabWidget_2.addTab(self.tab_instrument, "")
        self.tabWidget_2.addTab(self.tab_algorithmtrading, "")
        self.tabWidget_2.addTab(self.tab_listtdlog, "")
        self.tabWidget_2.addTab(self.tab_listmdlog, "")
        self.tabWidget_2.addTab(self.tab_historytd, "")
        self.tabWidget_2.addTab(self.tab_historymd, "")
        self.tabWidget_2.addTab(self.tab_backtestdata, "")
        self.tabWidget_2.addTab(self.tab_result, "")
        self.tabWidget_2.addTab(self.tab_faq, "")

        self.Button_AddStrategy = QPushButton("重新扫描策略目录新策略")
        self.Button_AddStrategy.setIcon(QtGui.QIcon('ico/ico_search.png'))
        self.Button_OpenStrategyPath = QPushButton("打开策略目录")
        self.Button_OpenStrategyPath.setIcon(QtGui.QIcon('ico/ico_path.png'))
        self.Button_StrategyPool = QPushButton("策略池设置")
        self.Button_StrategyPool.setIcon(QtGui.QIcon('ico/ico_pool.png'))
        self.Button_NewStrategyFile = QPushButton("新建策略")
        self.Button_NewStrategyFile.setIcon(QtGui.QIcon('ico/ico_new.png'))
        self.Button_SelectAll = QPushButton("选择全部")
        self.Button_SelectAll.setIcon(QtGui.QIcon('ico/ico_select.png'))
        self.Button_SelectNone = QPushButton("清除全部")
        self.Button_SelectNone.setIcon(QtGui.QIcon('ico/ico_selectnone.png'))

        self.Button_AddInstrumentGroup = QPushButton("添加合约组")
        self.Button_AddInstrumentGroup.setIcon(QtGui.QIcon('ico/ico_add.png'))
        self.Button_AboutInstrumentGroup = QPushButton("关于合约组")
        self.Button_AboutInstrumentGroup.setIcon(QtGui.QIcon('ico/ico_about.png'))
        self.Button_StrategyInstructions = QPushButton("策略模块使用说明")

        self.Button_StrategyFunction = QPushButton("")
        self.Button_AddInvestor = QPushButton("添加或修改账户")
        self.Button_AddInvestor.setIcon(QtGui.QIcon('ico/ico_user.ico'))

        self.Button_ModifyInvestor = QPushButton("如何申请穿透监管授权码")
        self.Button_AddInstrument = QPushButton("查询合约参数")
        self.Button_AddInstrument.setIcon(QtGui.QIcon('ico/ico_search.png'))
        self.Button_SelectMainInstrument = QPushButton("选择主力合约")
        self.Button_SelectMainInstrument.setIcon(QtGui.QIcon('ico/ico_maininstrument.png'))

        self.Button_Simnow = QPushButton("注册模拟账户（仅限工作日白天）")
        self.Button_Simnow.setIcon(QtGui.QIcon('ico/ico_user.png'))
        self.Button_Kaihu = QPushButton("开立实盘账户")
        self.Button_Kaihu.setIcon(QtGui.QIcon('ico/ico_user.png'))
        self.Button_Plus = QPushButton("Plus会员说明")
        self.Button_Plus.setIcon(QtGui.QIcon('ico/ico_about.png'))
        self.Button_Community = QPushButton("社区登录注册")
        self.Button_BandPlus = QPushButton("绑定期货账号获取Plus")
        self.Button_Buyplus = QPushButton("购买Plus")
        self.Button_OpenBackTestingPath = QPushButton("打开回测报告目录")
        self.Button_SetServiceUser = QPushButton("设置数据会员账户")
        self.Button_SetServiceUser.setIcon(QtGui.QIcon('ico/ico_user.ico'))

        self.Button_BuyService = QPushButton("购买数据服务会员")
        self.Button_BuyService.setIcon(QtGui.QIcon('ico/ico_data.png'))

        self.Button_ClearTdLog = QPushButton("清除历史交易日志文件")
        self.Button_ClearTdLog.setIcon(QtGui.QIcon('ico/ico_clean.png'))
        self.Button_ClearMdLog = QPushButton("清除历史行情日志文件")
        self.Button_ClearMdLog.setIcon(QtGui.QIcon('ico/ico_clean.png'))
        self.Button_ClearTodayTdLog = QPushButton("清空今日交易日志")
        self.Button_ClearTodayTdLog.setIcon(QtGui.QIcon('ico/ico_clean.png'))
        self.Button_ClearTodayMdLog = QPushButton("清空今日行情日志")
        self.Button_ClearTodayMdLog.setIcon(QtGui.QIcon('ico/ico_clean.png'))
        self.Button_OpenAlgorithmicTradingPath = QPushButton("打开算法交易目录")
        self.Button_OpenAlgorithmicTradingPath.setIcon(QtGui.QIcon('ico/ico_path.png'))

        self.Button_FaqKaihu = QPushButton("如何降低交易成本")
        self.Button_FaqKaihu.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_FaqDevelopmentEnvironment = QPushButton("开发环境")
        self.Button_FaqDevelopmentEnvironment.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq3 = QPushButton("FAQ3")
        self.Button_Faq3.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq4 = QPushButton("FAQ4")
        self.Button_Faq4.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq5 = QPushButton("FAQ5")
        self.Button_Faq5.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq6 = QPushButton("FAQ6")
        self.Button_Faq6.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq7 = QPushButton("FAQ7")
        self.Button_Faq7.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq8 = QPushButton("FAQ8")
        self.Button_Faq8.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq9 = QPushButton("FAQ9")
        self.Button_Faq9.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq10 = QPushButton("FAQ10")
        self.Button_Faq10.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq11 = QPushButton("FAQ11")
        self.Button_Faq11.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq12 = QPushButton("FAQ12")
        self.Button_Faq12.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq13 = QPushButton("FAQ13")
        self.Button_Faq13.setIcon(QtGui.QIcon('ico/ico_faq.png'))
        self.Button_Faq14 = QPushButton("FAQ14")
        self.Button_Faq14.setIcon(QtGui.QIcon('ico/ico_faq.png'))

        self.gridLayout_strategy = QtWidgets.QGridLayout(self.tab_strategy)
        self.gridLayout_strategy.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_strategy.setObjectName("gridLayout_strategy")

        self.gridLayout_instrumentgroup = QtWidgets.QGridLayout(self.tab_instrumentgroup)
        self.gridLayout_instrumentgroup.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_instrumentgroup.setObjectName("gridLayout_instrumentgroup")

        self.gridLayout_account = QtWidgets.QGridLayout(self.tab_account)
        self.gridLayout_account.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_account.setObjectName("gridLayout_account")

        self.table_account = QtWidgets.QTableWidget(self.tab_account)
        self.table_account.setObjectName("table_account")
        self.table_account.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_account.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_account.setColumnCount(10)
        self.table_account.setRowCount(1)
        self.table_account.setEditTriggers(QTableView.NoEditTriggers)
        self.table_account.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_account.setHorizontalHeaderLabels(
            ['期货公司BrokeID', '期货账户', '静态权益', '动态权益', '收益率', '可用资金', '仓位(风险度)', '手续费', '可取资金', '上次更新时间'])
        self.table_account.setColumnWidth(0, 80)
        self.table_account.setColumnWidth(1, 100)
        self.table_account.setColumnWidth(2, 100)
        self.table_account.setColumnWidth(3, 100)
        self.table_account.setColumnWidth(4, 80)
        self.table_account.setColumnWidth(5, 100)
        self.table_account.setColumnWidth(6, 80)
        self.table_account.setColumnWidth(7, 100)
        self.table_account.setColumnWidth(8, 100)
        self.table_account.setColumnWidth(9, 120)
        try:
            global config
            config = configparser.ConfigParser()
            # -read读取ini文件
            config.read('vnctptd.ini', encoding='utf-8')
            brokeid = config.get('setting', 'brokeid')
            investor = config.get('setting', 'investor')
            password = config.get('setting', 'password')
            appid = config.get('setting', 'appid')
            userproductinfo = config.get('setting', 'userproductinfo')
            authcode = config.get('setting', 'authcode')
            address1 = config.get('setting', 'address1')
            address2 = config.get('setting', 'address2')
            address3 = config.get('setting', 'address3')
            item = QTableWidgetItem(brokeid)
            self.table_account.setItem(0, 0, item)
            item = QTableWidgetItem(investor)
            self.table_account.setItem(0, 1, item)
            item = QTableWidgetItem('登录更新')  # 静态权益
            self.table_account.setItem(0, 2, item)
            item = QTableWidgetItem('登录更新')
            self.table_account.setItem(0, 3, item)
            item = QTableWidgetItem('0.0%')  # 今日盈亏
            self.table_account.setItem(0, 4, item)
            item = QTableWidgetItem('登录更新')
            self.table_account.setItem(0, 5, item)  # 可用权益
            item = QTableWidgetItem('登录更新')  # 仓位
            self.table_account.setItem(0, 6, item)
            item = QTableWidgetItem('登录更新')  # 手续费
            self.table_account.setItem(0, 7, item)
            item = QTableWidgetItem('登录更新')  # 可取资金
            self.table_account.setItem(0, 8, item)
            item = QTableWidgetItem('登录更新')
            self.table_account.setItem(0, 9, item)
        except Exception as e:
            print("login Error:" + repr(e))

        self.gridLayout_instrument = QtWidgets.QGridLayout(self.tab_instrument)
        self.gridLayout_instrument.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_instrument.setObjectName("gridLayout_tab_instrument")

        self.table_instrument = QtWidgets.QTableWidget(self.tab_instrument)
        self.table_instrument.setObjectName("table_instrument")
        self.table_instrument.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_instrument.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_instrument.setEditTriggers(QTableView.NoEditTriggers)
        self.table_instrument.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_instrument.doubleClicked.connect(self.Function_doubleClicked_Trade)
        self.table_instrument.setColumnCount(7)
        self.table_instrument.setRowCount(0)
        self.table_instrument.setHorizontalHeaderLabels(
            ['ID', '合约', '合约编码', '交易所', '1跳价差', '保证金', '手续费'])
        self.table_instrument.setColumnWidth(0, 120)
        self.table_instrument.setColumnWidth(1, 120)
        self.table_instrument.setColumnWidth(2, 120)
        self.table_instrument.setColumnWidth(3, 120)
        self.table_instrument.setColumnWidth(4, 120)
        self.table_instrument.setColumnWidth(5, 120)
        self.table_instrument.setColumnWidth(6, 120)
        self.table_instrument.setSortingEnabled(True)  # 设置表头可以自动排序
        self.gridLayout_instrument.addWidget(self.table_instrument, 0, 0, 2, 2)
        self.gridLayout_instrument.addWidget(self.Button_AddInstrument, 3, 0, 1, 1)
        self.gridLayout_instrument.addWidget(self.Button_SelectMainInstrument, 3, 1, 1, 1)
        # list_marketdata
        self.gridLayout_marketdata = QtWidgets.QGridLayout(self.tab_marketdata)
        self.gridLayout_marketdata.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_marketdata.setObjectName("gridLayout_marketdata")
        self.list_marketdata = QtWidgets.QListWidget(self.tab_marketdata)
        self.list_marketdata.setObjectName("list_marketdata")
        _translate = QtCore.QCoreApplication.translate
        __sortingEnabled = self.list_marketdata.isSortingEnabled()
        self.list_marketdata.setSortingEnabled(False)
        self.list_marketdata.setSortingEnabled(__sortingEnabled)
        self.gridLayout_marketdata.addWidget(self.list_marketdata, 0, 0, 1, 1)

        # 今日交易日志
        self.gridLayout_listtdlog = QtWidgets.QGridLayout(self.tab_listtdlog)
        self.gridLayout_listtdlog.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_listtdlog.setObjectName("gridLayout_listtdlog")
        self.list_listtdlog = QtWidgets.QListWidget(self.tab_listtdlog)
        self.list_listtdlog.setObjectName("list_listtdlog")
        _translate = QtCore.QCoreApplication.translate
        __sortingEnabled = self.list_listtdlog.isSortingEnabled()
        self.list_listtdlog.setSortingEnabled(False)
        self.list_listtdlog.setSortingEnabled(__sortingEnabled)
        self.gridLayout_listtdlog.addWidget(self.list_listtdlog, 0, 0, 1, 1)
        self.gridLayout_listtdlog.addWidget(self.Button_ClearTodayTdLog, 1, 0, 1, 1)

        # 今日行情日志
        self.gridLayout_listmdlog = QtWidgets.QGridLayout(self.tab_listmdlog)
        self.gridLayout_listmdlog.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_listmdlog.setObjectName("gridLayout_listmdlog")
        self.list_listmdlog = QtWidgets.QListWidget(self.tab_listmdlog)
        self.list_listmdlog.setObjectName("list_listmdlog")
        _translate = QtCore.QCoreApplication.translate
        __sortingEnabled = self.list_listmdlog.isSortingEnabled()
        self.list_listmdlog.setSortingEnabled(False)
        self.list_listmdlog.setSortingEnabled(__sortingEnabled)
        self.gridLayout_listmdlog.addWidget(self.list_listmdlog, 0, 0, 1, 1)
        self.gridLayout_listmdlog.addWidget(self.Button_ClearTodayMdLog, 1, 0, 1, 1)

        # 增值服务
        self.gridLayout_plus = QtWidgets.QGridLayout(self.tab_plus)
        self.gridLayout_plus.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_plus.setObjectName("gridLayout_plus")
        self.table_plus = QtWidgets.QTableWidget(self.tab_plus)
        self.table_plus.setObjectName("table_plus")
        self.table_plus.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_plus.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_plus.setColumnCount(7)
        self.table_plus.setRowCount(0)
        self.table_plus.setEditTriggers(QTableView.NoEditTriggers)
        self.table_plus.setHorizontalHeaderLabels(
            ['期货版Plus会员', '积分', '推荐人数', '多日K线数据', '有限期', '回测功能', '有效期'])
        self.table_plus.setColumnWidth(0, 120)
        self.table_plus.setColumnWidth(1, 120)
        self.table_plus.setColumnWidth(2, 80)
        self.table_plus.setColumnWidth(3, 120)
        self.table_plus.setColumnWidth(4, 120)
        self.table_plus.setColumnWidth(5, 120)
        self.table_plus.setColumnWidth(6, 120)
        self.table_plus.setRowHeight(0, 30)
        Trade_InstrumentBtn = QtWidgets.QPushButton('合约设置')
        Trade_InstrumentBtn.setFlat(True)
        Trade_InstrumentBtn.setStyleSheet('background-color:#ff0000;')
        Trade_InstrumentBtn.setStyleSheet('QPushButton{margin:3px}')
        self.table_plus.setCellWidget(0, 6, Trade_InstrumentBtn)
        Trade_BacktestingBtn = QtWidgets.QPushButton('回测')
        Trade_BacktestingBtn.setFlat(True)
        Trade_BacktestingBtn.setStyleSheet('background-color:#ff0000;')
        Trade_BacktestingBtn.setStyleSheet('QPushButton{margin:3px}')
        self.table_plus.setCellWidget(0, 7, Trade_BacktestingBtn)
        Trade_BacktestingBtn = QtWidgets.QPushButton('查看策略仓位')
        Trade_BacktestingBtn.setFlat(True)
        Trade_BacktestingBtn.setStyleSheet('background-color:#ff0000;')
        Trade_BacktestingBtn.setStyleSheet('QPushButton{margin:3px}')
        self.gridLayout_plus.addWidget(self.table_plus, 0, 0, 2, 2)
        self.gridLayout_plus.addWidget(self.Button_Plus, 2, 0, 1, 1)
        self.gridLayout_plus.addWidget(self.Button_Community, 2, 1, 1, 1)
        self.gridLayout_plus.addWidget(self.Button_BandPlus, 3, 0, 1, 1)
        self.gridLayout_plus.addWidget(self.Button_Buyplus, 3, 1, 1, 1)

        # 策略
        self.table_strategy = QtWidgets.QTableWidget(self.tab_strategy)
        self.table_strategy.setObjectName("table_strategy")
        self.table_strategy.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_strategy.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_strategy.setColumnCount(9)
        self.table_strategy.setRowCount(0)
        self.table_strategy.setEditTriggers(QTableView.NoEditTriggers)
        self.table_strategy.setHorizontalHeaderLabels(
            ['ID(勾选执行)', '策略文件名称', '仓位', '今日交易', '操作1', '操作2', '操作3', '操作4', '周期'])
        self.table_strategy.doubleClicked.connect(self.Function_doubleClicked_strategy)
        self.table_strategy.setColumnWidth(0, 60)
        self.table_strategy.setColumnWidth(1, 190)
        self.table_strategy.setColumnWidth(2, 80)
        self.table_strategy.setColumnWidth(3, 70)
        self.table_strategy.setColumnWidth(4, 70)
        self.table_strategy.setColumnWidth(5, 85)
        self.table_strategy.setColumnWidth(6, 70)
        self.table_strategy.setColumnWidth(7, 70)

        self.table_strategy.setColumnWidth(8, 100)
        self.table_strategy.setColumnWidth(9, 100)
        self.table_strategy.setRowHeight(0, 30)
        self.gridLayout_strategy.addWidget(self.table_strategy, 0, 0, 2, 6)
        self.gridLayout_strategy.addWidget(self.Button_AddStrategy, 3, 0, 1, 2)
        self.gridLayout_strategy.addWidget(self.Button_OpenStrategyPath, 3, 2, 1, 2)
        self.gridLayout_strategy.addWidget(self.Button_StrategyPool, 3, 4, 1, 2)
        self.gridLayout_strategy.addWidget(self.Button_NewStrategyFile, 4, 0, 1, 2)
        self.gridLayout_strategy.addWidget(self.Button_SelectAll, 4, 2, 1, 2)
        self.gridLayout_strategy.addWidget(self.Button_SelectNone, 4, 4, 1, 2)

        self.table_instrumentgroup = QtWidgets.QTableWidget(self.tab_instrumentgroup)
        self.table_instrumentgroup.setObjectName("table_instrumentgroup")
        self.table_instrumentgroup.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_instrumentgroup.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_instrumentgroup.setColumnCount(5)
        self.table_instrumentgroup.setRowCount(0)
        self.table_instrumentgroup.setEditTriggers(QTableView.NoEditTriggers)
        self.table_instrumentgroup.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_instrumentgroup.setHorizontalHeaderLabels(
            ['ID', '合约组名称', '选入合约数量', '备注', '操作'])
        self.table_instrumentgroup.doubleClicked.connect(self.Function_doubleClicked_strategy)
        self.table_instrumentgroup.setColumnWidth(0, 60)
        self.table_instrumentgroup.setColumnWidth(1, 290)
        self.table_instrumentgroup.setColumnWidth(2, 100)
        self.table_instrumentgroup.setColumnWidth(3, 100)
        self.table_instrumentgroup.setColumnWidth(4, 220)
        self.table_instrumentgroup.setRowHeight(0, 30)
        self.gridLayout_instrumentgroup.addWidget(self.table_instrumentgroup, 0, 0, 1, 2)
        self.gridLayout_instrumentgroup.addWidget(self.Button_AddInstrumentGroup, 1, 0, 1, 1)
        self.gridLayout_instrumentgroup.addWidget(self.Button_AboutInstrumentGroup, 1, 1, 1, 1)

        self.gridLayout_account.addWidget(self.table_account, 0, 0, 2, 2)
        self.gridLayout_account.addWidget(self.Button_AddInvestor, 2, 0, 1, 1)
        self.gridLayout_account.addWidget(self.Button_ModifyInvestor, 2, 1, 1, 1)
        self.gridLayout_account.addWidget(self.Button_Kaihu, 3, 0, 1, 1)
        self.gridLayout_account.addWidget(self.Button_Simnow, 3, 1, 1, 1)

        # 常见问题
        self.gridLayout_faq = QtWidgets.QGridLayout(self.tab_faq)
        self.gridLayout_faq.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_faq.setObjectName("gridLayout_faq")
        self.gridLayout_faq.addWidget(self.Button_FaqKaihu, 0, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_FaqDevelopmentEnvironment, 0, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq3, 1, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq4, 1, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq5, 2, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq6, 2, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq7, 3, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq8, 3, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq9, 4, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq10, 4, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq11, 5, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq12, 5, 1, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq13, 6, 0, 1, 1)
        self.gridLayout_faq.addWidget(self.Button_Faq14, 6, 1, 1, 1)

        # 算法交易
        self.gridLayout_algorithmtrading = QtWidgets.QGridLayout(self.tab_algorithmtrading)
        self.gridLayout_algorithmtrading.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_algorithmtrading.setObjectName("gridLayout_algorithmtrading")
        self.gridLayout.addWidget(self.tabWidget_2, 0, 0, 1, 1)
        self.gridLayout_historytd = QtWidgets.QGridLayout(self.tab_historytd)
        self.gridLayout_historytd.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_historytd.setObjectName("gridLayout_historytd")
        self.gridLayout_historymd = QtWidgets.QGridLayout(self.tab_historymd)
        self.gridLayout_historymd.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_historymd.setObjectName("gridLayout_historymd")
        self.gridLayout_backtestdata = QtWidgets.QGridLayout(self.tab_backtestdata)
        self.gridLayout_backtestdata.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_backtestdata.setObjectName("gridLayout_backtestdata")

        self.table_backtestdata = QtWidgets.QTableWidget(self.tab_backtestdata)
        self.table_backtestdata.setObjectName("table_backtestdata")
        self.table_backtestdata.verticalHeader().setVisible(True)  # 隐藏垂直表头
        self.table_backtestdata.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_backtestdata.setColumnCount(8)
        self.table_backtestdata.setSelectionMode(QAbstractItemView.SingleSelection)  # 设置只能选中一行
        self.table_backtestdata.setEditTriggers(QTableView.NoEditTriggers)
        self.table_backtestdata.setHorizontalHeaderLabels(
            ['ID', '合约', '开始日期', '结束日期', '数据大小', '周期', '进度', '操作'])
        self.table_backtestdata.setRowHeight(0, 30)
        self.table_backtestdata.setColumnWidth(0, 50)
        self.table_backtestdata.setColumnWidth(1, 120)
        self.table_backtestdata.setColumnWidth(2, 120)
        self.table_backtestdata.setColumnWidth(3, 120)
        self.table_backtestdata.setColumnWidth(4, 60)
        self.table_backtestdata.setColumnWidth(5, 60)
        self.table_backtestdata.setColumnWidth(6, 230)
        self.table_backtestdata.setColumnWidth(7, 120)
        self.gridLayout_backtestdata.addWidget(self.table_backtestdata, 0, 0, 2, 2)
        self.gridLayout_backtestdata.addWidget(self.Button_SetServiceUser, 2, 0, 1, 1)
        self.gridLayout_backtestdata.addWidget(self.Button_BuyService, 2, 1, 1, 1)

        # 历史交易日志标签
        self.table_historytd = QtWidgets.QTableWidget(self.tab_historytd)
        self.table_historytd.setObjectName("table_historytd")
        self.table_historytd.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_historytd.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_historytd.setColumnCount(3)
        self.table_historytd.setRowCount(0)
        self.table_historytd.setEditTriggers(QTableView.NoEditTriggers)
        self.table_historytd.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_historytd.setRowHeight(0, 30)
        self.table_historytd.setColumnWidth(0, 100)
        self.table_historytd.setColumnWidth(1, 400)
        self.table_historytd.setHorizontalHeaderLabels(
            ['ID', '文件（文件名为日期，双击打开日志）', '操作'])
        self.table_historytd.setColumnWidth(0, 0)
        self.table_historytd.setColumnWidth(1, 0)
        self.table_historytd.setColumnWidth(2, 0)
        self.table_historytd.doubleClicked.connect(self.Function_doubleClicked_historytd)
        self.gridLayout_historytd.addWidget(self.table_historytd, 0, 0, 1, 1)
        self.gridLayout_historytd.addWidget(self.Button_ClearTdLog, 1, 0, 1, 1)
        self.Button_ClearTdLog.clicked.connect(self.Function_ClearTdLog)

        self.gridLayout_result = QtWidgets.QGridLayout(self.tab_result)
        self.gridLayout_result.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_result.setObjectName("gridLayout_result")
        self.table_result = QtWidgets.QTableWidget(self.tab_result)
        self.table_result.setObjectName("table_result")
        self.table_result.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_result.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_result.setColumnCount(9)
        self.table_result.setRowCount(0)
        self.table_result.setEditTriggers(QTableView.NoEditTriggers)
        self.table_result.setHorizontalHeaderLabels(
            ['ID', '策略', '执行合约数', '胜率', '盈亏比', '今日交易', '合约设置', '回测', '查看策略仓位'])
        self.table_result.setRowHeight(0, 30)
        self.table_result.setColumnWidth(0, 50)
        self.table_result.setColumnWidth(1, 120)
        self.table_result.setColumnWidth(2, 120)
        self.table_result.setColumnWidth(3, 120)
        self.table_result.setColumnWidth(4, 60)
        self.table_result.setColumnWidth(5, 60)
        self.table_result.setColumnWidth(6, 120)
        self.table_result.setColumnWidth(7, 60)
        self.table_result.setColumnWidth(8, 60)
        self.gridLayout_result.addWidget(self.table_result, 0, 0, 2, 2)

        # 历史行情日志标签
        self.table_historymd = QtWidgets.QTableWidget(self.tab_historymd)
        self.table_historymd.setObjectName("table_historymd")
        self.table_historymd.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_historymd.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_historymd.setColumnCount(3)
        self.table_historymd.setRowCount(0)
        self.table_historymd.setEditTriggers(QTableView.NoEditTriggers)
        self.table_historymd.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_historymd.setRowHeight(0, 30)
        self.table_historymd.setColumnWidth(0, 100)
        self.table_historymd.setColumnWidth(1, 400)
        self.table_historymd.setHorizontalHeaderLabels(
            ['ID', '文件（文件名为日期，双击打开日志）', '操作'])
        self.table_historymd.setColumnWidth(0, 0)
        self.table_historymd.setColumnWidth(1, 0)
        self.table_historymd.setColumnWidth(2, 0)
        self.table_historymd.doubleClicked.connect(self.Function_doubleClicked_historymd)
        self.Trade_historymdBtn = QPushButton("打开日志")
        self.table_historymd.setCellWidget(0, 6, self.Trade_historymdBtn)
        self.Trade_historymdBtn.clicked.connect(self.Function_OpenLog_MD)
        self.gridLayout_historymd.addWidget(self.table_historymd, 0, 0, 1, 1)
        self.gridLayout_historymd.addWidget(self.Button_ClearMdLog, 1, 0, 1, 1)
        self.Button_ClearMdLog.clicked.connect(self.Function_ClearMdLog)

        # 算法交易
        self.table_algorithmtrading = QtWidgets.QTableWidget(self.tab_algorithmtrading)
        self.table_algorithmtrading.setObjectName("table_algorithmtrading")
        self.table_algorithmtrading.verticalHeader().setVisible(False)  # 隐藏垂直表头
        self.table_algorithmtrading.horizontalHeader().setVisible(True)  # 隐藏水平表头
        self.table_algorithmtrading.setColumnCount(7)
        self.table_algorithmtrading.setRowCount(1)
        self.table_algorithmtrading.setRowHeight(0, 30)
        self.table_algorithmtrading.setEditTriggers(QTableView.NoEditTriggers)
        self.table_algorithmtrading.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_algorithmtrading.setHorizontalHeaderLabels(
            ['交易算法', '算法交易路径', '节省滑点', '参数1', '参数2', '参数3', '参数4'])
        self.table_algorithmtrading.setColumnWidth(0, 120)
        self.table_algorithmtrading.setColumnWidth(1, 120)
        self.table_algorithmtrading.setColumnWidth(2, 120)
        self.table_algorithmtrading.setColumnWidth(3, 120)
        self.table_algorithmtrading.setColumnWidth(4, 120)
        self.table_algorithmtrading.setColumnWidth(5, 120)
        self.table_algorithmtrading.setColumnWidth(6, 120)
        self.gridLayout_algorithmtrading.addWidget(self.table_algorithmtrading, 0, 0, 1, 1)
        self.gridLayout_algorithmtrading.addWidget(self.Button_OpenAlgorithmicTradingPath, 1, 0, 1, 1)
        self.Button_OpenAlgorithmicTradingPath.clicked.connect(self.Function_OpenAlgorithmicTradingPath)
        self.table_algorithmtrading.doubleClicked.connect(self.Function_doubleClicked_algorithmtrading_limit)

        def function_item_clicked(self, QTableWidgetItem):
            check_state = QTableWidgetItem.checkState()
            row = QTableWidgetItem.row()
            if check_state == QtCore.Qt.Checked:
                if row not in self.delete_row:
                    self.delete_row.append(row)
            elif check_state == QtCore.Qt.Unchecked:
                if row in self.delete_row:
                    self.delete_row.remove(row)

        item = QTableWidgetItem(' 限价单')
        item.setCheckState(QtCore.Qt.Checked)
        self.table_algorithmtrading.setItem(0, 0, item)
        item = QTableWidgetItem('')
        self.table_algorithmtrading.setItem(0, 1, item)
        item = QTableWidgetItem('')
        self.table_algorithmtrading.setItem(0, 2, item)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tab_3 = QtWidgets.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.tab_3)
        self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.groupBox_3 = QtWidgets.QGroupBox(self.tab_3)
        self.list_explain = QtWidgets.QListWidget(self.tab_3)
        self.list_explain.setObjectName("list_explain")
        self.list_explain.setSortingEnabled(False)
        _translate = QtCore.QCoreApplication.translate
        __sortingEnabled = self.list_explain.isSortingEnabled()
        self.list_explain.setSortingEnabled(__sortingEnabled)
        self.gridLayout_3.addWidget(self.list_explain, 0, 0, 1, 1)

        self.tabWidget.addTab(self.tab_2, "")
        self.tabWidget.addTab(self.tab_3, "")
        self.verticalLayout_5.addWidget(self.tabWidget, 16)
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.Button_Start = QtWidgets.QPushButton(self.centralwidget)
        self.Button_Start.setCursor(QtGui.QCursor(Qt.PointingHandCursor))
        self.Button_Start.setObjectName("Button_Start")
        self.Button_Start.setSizePolicy(
            QtWidgets.QSizePolicy.Fixed, 0)
        self.horizontalLayout.addWidget(self.Button_Start)
        self.Button_Start.setStyleSheet("QPushButton{border-image: url(onstart1.png)}")
        self.Button_Start.setFixedSize(165, 60)
        self.Button_Stop = QtWidgets.QPushButton(self.centralwidget)
        self.Button_Stop.setCursor(QtGui.QCursor(Qt.PointingHandCursor))
        self.Button_Stop.setEnabled(False)
        self.Button_Stop.setObjectName("Button_Stop")
        self.Button_Stop.setSizePolicy(QtWidgets.QSizePolicy.Fixed, 0)
        self.Button_Stop.setStyleSheet("QPushButton{border-image: url(onstop2.png)}")
        self.Button_Stop.setFixedSize(165, 60)
        self.horizontalLayout.addWidget(self.Button_Stop)
        self.lab_run = QLabel()
        self.lab_run.setPixmap(QPixmap('ico/ico_alert_stop.png'))
        self.horizontalLayout.addWidget(self.lab_run)
        self.lab_md = QLabel()
        self.lab_md.setPixmap(QPixmap('ico/ico_error_mdconnect.png'))
        self.horizontalLayout.addWidget(self.lab_md)
        self.lab_td = QLabel()
        self.lab_td.setPixmap(QPixmap('ico/ico_error_tdconnect.png'))
        self.horizontalLayout.addWidget(self.lab_td)
        self.toolButton = QtWidgets.QToolButton(self.centralwidget)
        self.toolButton.setPopupMode(QtWidgets.QToolButton.InstantPopup)
        self.toolButton.setObjectName("toolButton")
        self.horizontalLayout.addWidget(self.toolButton)
        self.verticalLayout_5.addLayout(self.horizontalLayout, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1068, 23))
        self.menubar.setObjectName("menubar")
        self.menuMenu_nav1 = QtWidgets.QMenu(self.menubar)
        self.menuMenu_nav1.setObjectName("menuMenu")
        self.menuMenu_nav2 = QtWidgets.QMenu(self.menubar)
        self.menuMenu_nav2.setObjectName("menuMenub")
        self.menuMenu_nav3 = QtWidgets.QMenu(self.menubar)
        self.menuMenu_nav3.setObjectName("menuMenub")
        self.menuSubmenu_2 = QtWidgets.QMenu(self.menuMenu_nav1)
        self.menuSubmenu_2.setObjectName("menuSubmenu_2")
        MainWindow.setMenuBar(self.menubar)
        self.dockWidget1 = QtWidgets.QDockWidget(MainWindow)
        self.dockWidget1.setObjectName("dockWidget1")
        self.dockWidgetContents = QtWidgets.QWidget()
        self.dockWidgetContents.setObjectName("dockWidgetContents")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.dockWidgetContents)
        self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")
        self.comboBox_kline = QtWidgets.QComboBox()
        # self.comboBox_kline.setFixedWidth(180)
        self.comboBox_kline.setObjectName("comboBox_kline")
        self.comboBox_kline.setFixedWidth(180)
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.comboBox_kline.addItem("")
        self.verticalLayout.addWidget(self.comboBox_kline)
        self.verticalLayout.addStretch(1)
        self.comboBox_exchange = QtWidgets.QComboBox()
        self.comboBox_exchange.setFixedWidth(180)
        self.comboBox_exchange.setObjectName("comboBox_exchange")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.comboBox_exchange.addItem("")
        self.verticalLayout.addWidget(self.comboBox_exchange)
        self.verticalLayout.addStretch(1)  # 与上面1：1 空白拉伸
        self.comboBox_instrument = QtWidgets.QComboBox()
        self.comboBox_instrument.setFixedWidth(180)
        self.comboBox_instrument.setObjectName("comboBox_instrument")
        self.comboBox_instrument.addItem("选择合约类型编码")
        self.verticalLayout.addWidget(self.comboBox_instrument)
        self.verticalLayout.addStretch(1)  # 与上面1：1 空白拉伸
        self.comboBox_instrumentid = QtWidgets.QComboBox()
        self.comboBox_instrumentid.setFixedWidth(180)
        self.comboBox_instrumentid.setObjectName("comboBox_instrumentid")
        self.comboBox_kline.activated.connect(lambda: self.to_comboBox_klineperiod(self.comboBox_kline.currentText()))
        self.comboBox_exchange.activated.connect(lambda: self.to_comboBox_1(self.comboBox_exchange.currentText()))
        self.comboBox_instrument.activated.connect(lambda: self.to_comboBox_2(self.comboBox_instrument.currentText()))
        self.comboBox_instrumentid.activated.connect(
            lambda: self.to_comboBox_3(self.comboBox_instrumentid.currentText()))

        self.verticalLayout_2.addLayout(self.verticalLayout)
        self.frame_comboBox = QtWidgets.QFrame(self.comboBox_kline)
        self.frame_comboBox.setMinimumSize(QtCore.QSize(0, 0))
        self.frame_comboBox.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_comboBox.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_comboBox.setLineWidth(3)
        self.frame_comboBox.setObjectName("frame_comboBox")
        self.verticalLayout.addWidget(self.frame_comboBox)

        self.gridLayout_comboBox = QtWidgets.QGridLayout(self.frame_comboBox)
        self.gridLayout_comboBox.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_comboBox.setObjectName("gridLayout_optionalstock222")

        self.gridLayout_comboBox.addWidget(self.comboBox_kline, 4, 0, 1, 1)
        self.gridLayout_comboBox.addWidget(self.comboBox_exchange, 4, 1, 1, 1)
        self.gridLayout_comboBox.addWidget(self.comboBox_instrument, 4, 2, 1, 1)
        self.gridLayout_comboBox.addWidget(self.comboBox_instrumentid, 4, 3, 1, 1)

        # K线图位置
        self.item = module_dlg.CandlestickItem(data_kline)
        npdata = np.array(data_kline)
        self.wkline = pg.GraphicsWindow()
        self.wkline.setWindowTitle('主视图K线图')
        self.plt_kline = self.wkline.addPlot(1, 1, title="K线图")
        self.plt_kline.addItem(self.item)
        self.plt_kline.showGrid(True, True)
        self.plt_kline.setMouseEnabled(x=True, y=True)
        self.verticalLayout.addWidget(self.wkline)
        self.wkline.showMaximized()

        # 分时图
        self.winmarket = pg.GraphicsLayoutWidget(show=True)
        self.winmarket.setWindowTitle('闪电图')
        self.plt_market = self.winmarket.addPlot(title="闪电图")
        # plt_market.setAutoVisibleOnly(y=True)
        self.curve_market = self.plt_market.plot()
        self.plt_market.setMouseEnabled(x=False, y=False)  # 禁用轴操作
        self.verticalLayout.addWidget(self.winmarket)
        self.winmarket.showMaximized()

        # Tab1 实时资金曲线位置
        self.win = pg.GraphicsLayoutWidget(show=True)
        self.win.setWindowTitle('实时资金曲线(10秒取样1次)')
        self.plt_realtime = self.win.addPlot(title="实时资金曲线(10秒取样1次)")
        self.curve_realtime = self.plt_realtime.plot(pen='y')
        self.plt_realtime.setMouseEnabled(x=False, y=False)  # 禁用轴操作
        self.verticalLayout.addWidget(self.win)
        self.win.showMaximized()

        # 进度条
        self.progressBar = QtWidgets.QProgressBar(self.dockWidgetContents)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setFormat("仓位：%p%")
        self.progressBar.setObjectName("总仓位")
        self.verticalLayout.addWidget(self.progressBar)
        # 决定绘图多窗口
        self.verticalLayout_2.addLayout(self.verticalLayout)

        self.Button_h = []

        self.temps = QtWidgets.QPushButton('最近访问1')
        self.temps.setObjectName("Button_h1")
        self.temps.clicked.connect(self.Function_Buttonclickh1)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问2')
        self.temps.setObjectName("Button_h2")
        self.temps.clicked.connect(self.Function_Buttonclickh2)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问3')
        self.temps.setObjectName("Button_h3")
        self.temps.clicked.connect(self.Function_Buttonclickh3)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问4')
        self.temps.setObjectName("Button_h4")
        self.temps.clicked.connect(self.Function_Buttonclickh4)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问5')
        self.temps.setObjectName("Button_h5")
        self.temps.clicked.connect(self.Function_Buttonclickh5)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问6')
        self.temps.setObjectName("Button_h6")
        self.temps.clicked.connect(self.Function_Buttonclickh6)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问7')
        self.temps.setObjectName("Button_h7")
        self.temps.clicked.connect(self.Function_Buttonclickh7)
        self.Button_h.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近访问8')
        self.temps.setObjectName("Button_h8")
        self.temps.clicked.connect(self.Function_Buttonclickh8)
        self.Button_h.append(self.temps)

        self.Button_t = []
        self.temps = QtWidgets.QPushButton('最近交易1')
        self.temps.setObjectName("Button_t1")
        self.temps.clicked.connect(self.Function_Buttonclickt1)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易2')
        self.temps.setObjectName("Button_t2")
        self.temps.clicked.connect(self.Function_Buttonclickt2)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易3')
        self.temps.setObjectName("Button_t3")
        self.temps.clicked.connect(self.Function_Buttonclickt3)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易4')
        self.temps.setObjectName("Button_t4")
        self.temps.clicked.connect(self.Function_Buttonclickt4)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易5')
        self.temps.setObjectName("Button_t5")
        self.temps.clicked.connect(self.Function_Buttonclickt5)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易6')
        self.temps.setObjectName("Button_t6")
        self.temps.clicked.connect(self.Function_Buttonclickt6)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易7')
        self.temps.setObjectName("Button_t7")
        self.temps.clicked.connect(self.Function_Buttonclickt7)
        self.Button_t.append(self.temps)

        self.temps = QtWidgets.QPushButton('最近交易8')
        self.temps.setObjectName("Button_t8")
        self.temps.clicked.connect(self.Function_Buttonclickt8)
        self.Button_t.append(self.temps)

        self.Button_zx = []
        self.temps = QtWidgets.QPushButton('自选1')
        self.temps.setObjectName("Button_zx1")
        self.temps.clicked.connect(self.Function_Buttonclickz1)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选2')
        self.temps.setObjectName("Button_zx2")
        self.temps.clicked.connect(self.Function_Buttonclickz2)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选3')
        self.temps.setObjectName("Button_zx3")
        self.temps.clicked.connect(self.Function_Buttonclickz3)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选4')
        self.temps.setObjectName("Button_zx4")
        self.temps.clicked.connect(self.Function_Buttonclickz4)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选5')
        self.temps.setObjectName("Button_zx5")
        self.temps.clicked.connect(self.Function_Buttonclickz5)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选6')
        self.temps.setObjectName("Button_zx6")
        self.temps.clicked.connect(self.Function_Buttonclickz6)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选7')
        self.temps.setObjectName("Button_zx7")
        self.temps.clicked.connect(self.Function_Buttonclickz7)
        self.Button_zx.append(self.temps)

        self.temps = QtWidgets.QPushButton('自选8')
        self.temps.setObjectName("Button_zx8")
        self.temps.clicked.connect(self.Function_Buttonclickz8)
        self.Button_zx.append(self.temps)

        self.frame = QtWidgets.QFrame(self.Button_h[0])
        self.frame.setMinimumSize(QtCore.QSize(0, 0))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setLineWidth(3)
        self.frame.setObjectName("frame")
        self.verticalLayout.addWidget(self.frame)

        self.gridLayout_optionalstock = QtWidgets.QGridLayout(self.frame)
        self.gridLayout_optionalstock.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_optionalstock.setObjectName("gridLayout_optionalstock")
        self.gridLayout_optionalstock.addWidget(self.Button_h[0], 1, 0, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[1], 1, 1, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[2], 1, 2, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[3], 1, 3, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[4], 1, 4, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[5], 1, 5, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[6], 1, 6, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_h[7], 1, 7, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[0], 2, 0, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[1], 2, 1, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[2], 2, 2, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[3], 2, 3, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[4], 2, 4, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[5], 2, 5, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[6], 2, 6, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_t[7], 2, 7, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[0], 3, 0, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[1], 3, 1, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[2], 3, 2, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[3], 3, 3, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[4], 3, 4, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[5], 3, 5, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[6], 3, 6, 1, 1)
        self.gridLayout_optionalstock.addWidget(self.Button_zx[7], 3, 7, 1, 1)

        geo = self.Button_h[0].geometry()
        geo.moveCenter(self.frame.rect().center())

        self.verticalLayout_2.addWidget(self.frame)
        self.dockWidget1.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget1)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.dockWidgetContents_2 = QtWidgets.QWidget()
        self.dockWidgetContents_2.setObjectName("dockWidgetContents_2")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.dockWidgetContents_2)
        self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_3.setObjectName("gridLayout_3")

        self.win5 = pg.GraphicsLayoutWidget(show=True)
        self.win5.setWindowTitle('资金曲线')
        self.plt_backtest = self.win5.addPlot(title="资金曲线")
        self.curve_backtest = self.plt_backtest.plot(pen='y')
        self.plt_backtest.setMouseEnabled(x=False, y=False)
        self.gridLayout_3.addWidget(self.win5, 1, 0, 1, 1)
        self.win5.showMaximized()

        self.Button_OpenDll = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_OpenDll.setObjectName("Button_OpenDll")
        self.Button_CloseDll = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_CloseDll.setObjectName("Button_CloseDll")
        self.Button_StrategyManage_SingleThread = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_StrategyManage_SingleThread.setObjectName("Button_StrategyManage_SingleThread")
        self.Button_StrategyManage_MulitProcess = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_StrategyManage_MulitProcess.setObjectName("Button_StrategyManage_MulitProcess")
        self.Button_KlineSource_RealTimeTick = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_KlineSource_RealTimeTick.setObjectName("Button_KlineSource_RealTimeTick")
        self.Button_KlineSource_ServerToday = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_KlineSource_ServerToday.setObjectName("Button_KlineSource_ServerToday")
        self.Button_KlineSource_ServerMultiday = QtWidgets.QAction(MainWindow, checkable=True)
        self.Button_KlineSource_ServerMultiday.setObjectName("Button_KlineSource_ServerMultiday")
        self.Button_CloseDll.setChecked(True)
        self.Button_StrategyManage_SingleThread.setChecked(True)
        self.Navgiate1 = QtWidgets.QAction(MainWindow)
        self.Navgiate1.setObjectName("Navgiate1")
        self.Navgiate2 = QtWidgets.QAction(MainWindow)
        self.Navgiate2.setObjectName("Navgiate2")
        self.Navgiate3 = QtWidgets.QAction(MainWindow)
        self.Navgiate3.setObjectName("Navgiate3")
        self.Navgiate4 = QtWidgets.QAction(MainWindow)
        self.Navgiate4.setObjectName("Navgiate4")
        self.Navgiate5 = QtWidgets.QAction(MainWindow)
        self.Navgiate5.setObjectName("Navgiate5")
        self.Navgiate6 = QtWidgets.QAction(MainWindow)
        self.Navgiate6.setObjectName("Navgiate6")
        self.Navgiate7 = QtWidgets.QAction(MainWindow)
        self.Navgiate7.setObjectName("Navgiate7")
        self.Navgiate8 = QtWidgets.QAction(MainWindow)
        self.Navgiate8.setObjectName("Navgiate8")
        self.Navgiate1_C = QtWidgets.QAction(MainWindow)
        self.Navgiate1_C.setObjectName("Navgiate1_C")
        self.menuSubmenu_2.addAction(self.Navgiate2)
        self.menuSubmenu_2.addAction(self.Navgiate1_C)
        self.menuMenu_nav1.addAction(self.Button_OpenDll)
        self.menuMenu_nav1.addAction(self.Button_CloseDll)
        self.menuMenu_nav2.addAction(self.Button_StrategyManage_SingleThread)
        self.menuMenu_nav2.addAction(self.Button_StrategyManage_MulitProcess)
        self.menuMenu_nav3.addAction(self.Button_KlineSource_RealTimeTick)
        self.menuMenu_nav3.addAction(self.Button_KlineSource_ServerToday)
        self.menuMenu_nav3.addAction(self.Button_KlineSource_ServerMultiday)
        self.menubar.addAction(self.menuMenu_nav1.menuAction())
        self.menubar.addAction(self.menuMenu_nav2.menuAction())
        self.menubar.addAction(self.menuMenu_nav3.menuAction())
        self.toolBar.addAction(self.Navgiate1)
        self.toolBar.addAction(self.Navgiate2)
        self.toolBar.addAction(self.Navgiate3)
        self.toolBar.addAction(self.Navgiate4)
        self.toolBar.addAction(self.Navgiate5)
        self.toolBar.addAction(self.Navgiate6)
        self.toolBar.addAction(self.Navgiate7)
        self.toolBar.addAction(self.Navgiate8)
        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        self.toolBox1.setCurrentIndex(2)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.toolButton, self.comboBox_kline)
        MainWindow.setTabOrder(self.toolButton, self.comboBox_exchange)
        MainWindow.setTabOrder(self.toolButton, self.comboBox_instrument)
        MainWindow.setTabOrder(self.toolButton, self.comboBox_instrumentid)

    class VNMainWindow(QtWidgets.QMainWindow):
        def __init__(self, *args, **kwargs):
            super(QtWidgets.QMainWindow, self).__init__(*args, **kwargs)
            self.setWindowTitle("VNPY官方[社区开源版] (http://www.vnpy.cn 探索更真实的量化交易世界)")
            self.setWindowFlags(QtCore.Qt.WindowMinMaxButtonsHint | QtCore.Qt.WindowCloseButtonHint)
            self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)  # 置顶
            self.setWindowFlags(QtCore.Qt.Widget)  # 取消置顶

        def OnClosePythonProcess(self):
            if 'python.exe' in os.popen('tasklist /FI "IMAGENAME eq python.exe"').read():
                # 程序退出时，终止python.exe进程，若要消除乱码，需设置IDE编码格式
                os.system('taskkill /f /im "python.exe"')

        def closeEvent(self, event):
            messagebox = QMessageBox(None)
            messagebox.setIcon(QMessageBox.Warning)
            messagebox.setText(('确认退出\nVNPY量化交易客户端吗？'))
            messagebox.setWindowTitle(('系统提示'))
            messagebox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
            buttonY = messagebox.button(QMessageBox.Yes)
            buttonY.setText('确定退出')
            buttonN = messagebox.button(QMessageBox.No)
            buttonN.setText('取消')
            buttonY.setIcon(QtGui.QIcon('ico/ico_yes.png'))
            buttonN.setIcon(QtGui.QIcon('ico/ico_no.png'))
            reply = messagebox.exec_()
            if messagebox.clickedButton() == buttonY:
                self.OnClosePythonProcess()
                event.accept()
            elif messagebox.clickedButton() == buttonN:
                event.ignore()

    # 更新回测资金曲线
    def updatebacktestingUi(self, newdata):
        def update_backtesting(newdata):
            global data_backtesting, count
            data_backtesting.append(newdata)
            if len(data_backtesting) > 100:
                data_backtesting.pop(0)
            self.curve_backtesting.setData(np.hstack(data_backtesting))
            count += 1

        for i in range(101):
            update_backtesting(newdata)

    # 从文件读取更新当日K线图
    def UpdateKlineUIFromFile(self, InstrumentID, TradingDay):
        try:
            global kid, count
            kid = 1
            fname = globalvar.currpath + "\\data_today\\" + InstrumentID + ".csv"
            print('filename: ' + fname)
            globalvar.ticklist = []
            if os.path.isfile(fname):
                for line in open(fname):
                    QApplication.processEvents()
                    ld = line.split(',')
                    temp = (kid,
                            float(ld[0]),
                            float(ld[1]),
                            float(ld[3]),
                            float(ld[4]),
                            float(ld[5]),
                            int(ld[6]))
                    globalvar.data_kline_M1.append(temp)

                    tempstr = str(int(float(ld[1]) * 10000))
                    tempstr_list = list(tempstr)
                    tempstr_list.insert(len(tempstr_list) - 2, ':')
                    tempstr = ''.join(tempstr_list)
                    globalvar.ticklist.append(ld[0] + "\n" + tempstr)
                    ld[1] = ld[1].ljust(8, '0')
                    ld[1] = '{:0>8s}'.format(ld[1])
                    tdatetime = ld[0][0:4] + "-" + ld[0][4:6] + "-" + ld[0][6:8] + " " + ld[1][2:4] + ":" + ld[1][
                                                                                                            4:6] + ":" + \
                                ld[1][6:8]
                    globalvar.dict_dataframe_kline_M1[InstrumentID] = globalvar.dict_dataframe_kline_M1[
                        InstrumentID].append({
                        'datetime': tdatetime,
                        'recordid': '{:0>8s}'.format(str(kid)),
                        'tradingday': ld[0],
                        'klinetime': ld[1],
                        'instrumentid': ld[2],
                        'open': float(ld[3]),
                        'close': float(ld[4]),
                        'low': float(ld[5]),
                        'high': float(ld[6]),
                        'vol': int(ld[7]),
                    }, ignore_index=True)
                    kid = kid + 1
            self.plt_kline.removeItem(self.item)

            self.item = module_dlg.CandlestickItem(globalvar.data_kline_M1)  # 原始数据,对应（0,0）幅图
            try:
                self.plt_kline.addItem(self.item)
                count += 1
            except Exception as e:
                print("UpdateKlineUIFromFileB Error:" + repr(e))

            # 横坐标刻度
            xax = self.plt_kline.getAxis('bottom')  # 坐标轴x
            xdict = dict(enumerate(globalvar.ticklist))
            xax.setTicks([xdict.items()])
        except Exception as e:
            print("UpdateKlineUIFromFile Error:" + repr(e))

    def UpdateKlineUIFromFileBakUp(self, InstrumentID, TradingDay):
        try:
            global kid, count
            kid = 1
            fname = globalvar.currpath + "\\data_today\\" + InstrumentID + ".csv"
            print('filename: ' + fname)
            globalvar.ticklist = []
            if os.path.isfile(fname):
                for line in open(fname):
                    ld = line.split(',')
                    temp = (kid,
                            float(ld[0]),
                            float(ld[1]),
                            float(ld[3]),
                            float(ld[4]),
                            float(ld[5]),
                            int(ld[6]))
                    globalvar.data_kline_M1.append(temp)
                    tempstr = str(int(float(ld[1]) * 10000))
                    tempstr_list = list(tempstr)
                    tempstr_list.insert(len(tempstr_list) - 2, ':')
                    tempstr = ''.join(tempstr_list)
                    globalvar.ticklist.append(ld[0] + "\n" + tempstr)
                    ld[1] = ld[1].ljust(8, '0')
                    ld[1] = '{:0>8s}'.format(ld[1])
                    tdatetime = ld[0][0:4] + "-" + ld[0][4:6] + "-" + ld[0][6:8] + " " + ld[1][2:4] + ":" + ld[1][
                                                                                                            4:6] + ":" + \
                                ld[1][6:8]
                    globalvar.dict_dataframe_kline_M1[InstrumentID] = globalvar.dict_dataframe_kline_M1[
                        InstrumentID].append({
                        'datetime': tdatetime,
                        'recordid': '{:0>8s}'.format(str(kid)),
                        'tradingday': ld[0],
                        'klinetime': ld[1],
                        'instrumentid': ld[2],
                        'open': float(ld[3]),
                        'close': float(ld[4]),
                        'low': float(ld[5]),
                        'high': float(ld[6]),
                        'vol': int(ld[7]),
                    }, ignore_index=True)
                    kid = kid + 1
            self.plt_kline.removeItem(self.item)

            self.item = module_dlg.CandlestickItem(globalvar.data_kline_M1)  # 原始数据,对应（0,0）幅图
            try:
                self.plt_kline.addItem(self.item)
                count += 1
            except Exception as e:
                print("UpdateKlineUIFromFileB Error:" + repr(e))
            # 横坐标刻度
            xax = self.plt_kline.getAxis('bottom')  # 坐标轴x
            xdict = dict(enumerate(globalvar.ticklist))
            xax.setTicks([xdict.items()])
        except Exception as e:
            print("UpdateKlineUIFromFile Error:" + repr(e))

    def dateprevious(self, year, mouth, day):
        list_mouth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        if day == 1:
            if mouth == 1:
                year = year - 1
                mouth = 12
                day = list_mouth[mouth - 1]
            else:
                mouth = mouth - 1
                day = list_mouth[mouth - 1]
                if day == 28:
                    if year % 4 == 0:
                        day = 29
        else:
            day = day - 1
        return year * 10000 + mouth * 100 + day

    # 从文件读取更新多日M1 K线图
    def UpdateMultiKlineUIFromFile(self, InstrumentID, TradingDay):
        global kid, count
        kid = 1
        TradingDaylist = []
        globalvar.ticklist = []
        newTradingDay = TradingDay
        for addday in range(10):
            tyear = int(str(newTradingDay)[0:4])
            tmonth = int(str(newTradingDay)[4:6])
            tday = int(str(newTradingDay)[6:8])
            newTradingDay = self.dateprevious(tyear, tmonth, tday)
            TradingDaylist.append(newTradingDay)
        TradingDaylist.reverse()
        for addday in range(10):
            fname = globalvar.currpath + "\\data_multiday\\" + InstrumentID + "\\" + str(
                TradingDaylist[addday]) + ".csv"
            if os.path.isfile(fname):
                for line in open(fname):
                    QApplication.processEvents()
                    ld = line.split(',')
                    temp = (kid,
                            float(ld[0]),
                            float(ld[1]),
                            float(ld[3]),
                            float(ld[4]),
                            float(ld[5]),
                            int(ld[6]))
                    globalvar.data_kline_M1.append(temp)

                    tempstr = str(int(float(ld[1]) * 10000))
                    tempstr_list = list(tempstr)
                    tempstr_list.insert(len(tempstr_list) - 2, ':')
                    tempstr = ''.join(tempstr_list)
                    globalvar.ticklist.append(ld[0] + "\n" + tempstr)
                    ld[1] = ld[1].ljust(8, '0')
                    ld[1] = '{:0>8s}'.format(ld[1])
                    tdatetime = ld[0][0:4] + "-" + ld[0][4:6] + "-" + ld[0][6:8] + " " + ld[1][2:4] + ":" + ld[1][
                                                                                                            4:6] + ":" + \
                                ld[1][6:8]
                    globalvar.dict_dataframe_kline_M1[InstrumentID] = globalvar.dict_dataframe_kline_M1[
                        InstrumentID].append({
                        'datetime': tdatetime,
                        'recordid': '{:0>8s}'.format(str(kid)),
                        'tradingday': ld[0],
                        'klinetime': ld[1],
                        'instrumentid': ld[2],
                        'open': float(ld[3]),
                        'close': float(ld[4]),
                        'low': float(ld[5]),
                        'high': float(ld[6]),
                        'vol': int(ld[7]),
                    }, ignore_index=True)

                    kid = kid + 1
        fname = globalvar.currpath + "\\data_multiday\\" + InstrumentID + "\\" + str(TradingDay) + ".csv"

        if os.path.isfile(fname):
            for line in open(fname):
                QApplication.processEvents()
                ld = line.split(',')
                temp = (kid,
                        float(ld[0]),
                        float(ld[1]),
                        float(ld[3]),
                        float(ld[4]),
                        float(ld[5]),
                        int(ld[6]))
                globalvar.data_kline_M1.append(temp)

                tempstr = str(int(float(ld[1]) * 10000))
                tempstr_list = list(tempstr)
                tempstr_list.insert(len(tempstr_list) - 2, ':')
                tempstr = ''.join(tempstr_list)

                globalvar.ticklist.append(ld[0] + "\n" + tempstr)
                ld[1] = ld[1].ljust(8, '0')
                ld[1] = '{:0>8s}'.format(ld[1])
                tdatetime = ld[0][0:4] + "-" + ld[0][4:6] + "-" + ld[0][6:8] + " " + ld[1][2:4] + ":" + ld[1][
                                                                                                        4:6] + ":" + ld[
                                                                                                                         1][
                                                                                                                     6:8]
                globalvar.dict_dataframe_kline_M1[InstrumentID] = globalvar.dict_dataframe_kline_M1[
                    InstrumentID].append({
                    'datetime': tdatetime,
                    'recordid': '{:0>8s}'.format(str(kid)),
                    'tradingday': ld[0],
                    'klinetime': ld[1],
                    'instrumentid': ld[2],
                    'open': float(ld[3]),
                    'close': float(ld[4]),
                    'low': float(ld[5]),
                    'high': float(ld[6]),
                    'vol': int(ld[7]),
                }, ignore_index=True)

                kid = kid + 1
        self.plt_kline.removeItem(self.item)
        self.item = module_dlg.CandlestickItem(globalvar.data_kline_M1)  # 原始数据,对应（0,0）幅图
        try:
            self.plt_kline.addItem(self.item)
            count += 1
        except Exception as e:
            print("UpdateMultiKlineUIFromFile Error:" + repr(e))

        # 横坐标刻度
        xax = self.plt_kline.getAxis('bottom')  # 坐标轴x
        xdict = dict(enumerate(globalvar.ticklist))
        xax.setTicks([xdict.items()])

    # 更新K线图
    def updateklineUi(self, InstrumentID0):
        InstrumentID = InstrumentID0.decode('utf-8')
        if globalvar.md:
            try:
                global lasttime
                global kid, count
                kid = kid + 1
                if lasttime != globalvar.md.GetKline(InstrumentID, 1)[0].KlineTime:
                    print('updateklineUi:' + str(lasttime))
                    lasttime = globalvar.md.GetKline(InstrumentID, 1)[0].KlineTime
                    thiskid = globalvar.data_kline_M1[len(globalvar.data_kline_M1) - 1][0] + 1
                    temp = (
                        thiskid,
                        float(globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay.decode('utf-8')),
                        globalvar.md.GetKline(InstrumentID, 1)[0].KlineTime,
                        globalvar.md.GetKline(InstrumentID, 1)[0].Open,
                        globalvar.md.GetKline(InstrumentID, 1)[0].Close,
                        globalvar.md.GetKline(InstrumentID, 1)[0].Low,
                        globalvar.md.GetKline(InstrumentID, 1)[0].High
                    )
                    globalvar.data_kline_M1.append(temp)
                    print('data_kline_M1: ' + str(globalvar.data_kline_M1))
                    tempstr = str(int(float(globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay)))
                    tempstr_list = list(tempstr)
                    tempstr = ''.join(tempstr_list)
                    klinetimestr = str(globalvar.md.GetKline(InstrumentID, 1)[0].KlineTime)
                    globalvar.ticklist.append(tempstr + "\n" + klinetimestr)
                    TradingDay = str(globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay,
                                     encoding="utf-8").ljust(8, '0')
                    TradingDay = '{:0>8s}'.format(TradingDay)
                    tdatetime = klinetimestr[0:4] + "-" + klinetimestr[4:6] + "-" + klinetimestr[
                                                                                    6:8] + " " + TradingDay[
                                                                                                 2:4] + ":" + TradingDay[
                                                                                                              4:6] + ":" + TradingDay[
                                                                                                                           6:8]

                    try:
                        if globalvar.notfirstupdateklineUi:
                            InstrumentID_key = InstrumentID
                            globalvar.dict_dataframe_kline_M1[InstrumentID_key] = globalvar.dict_dataframe_kline_M1[
                                InstrumentID_key].append({
                                'datetime': tdatetime,
                                'recordid': '{:0>8s}'.format(str(thiskid)),
                                'tradingday': float(
                                    globalvar.md.GetKline(InstrumentID, 1)[0].TradingDay.decode('utf-8')),
                                'klinetime': klinetimestr,
                                'instrumentid': InstrumentID,
                                'open': globalvar.md.GetKline(InstrumentID, 1)[0].Open,
                                'close': globalvar.md.GetKline(InstrumentID, 1)[0].Close,
                                'low': globalvar.md.GetKline(InstrumentID, 1)[0].Low,
                                'high': globalvar.md.GetKline(InstrumentID, 1)[0].High,
                                'vol': globalvar.md.GetKline(InstrumentID, 1)[0].Volume,
                            }, ignore_index=True)

                            self.plt_kline.removeItem(self.item)
                            self.item = module_dlg.CandlestickItem(globalvar.data_kline_M1)  # 原始数据,对应（0,0）幅图
                        else:
                            globalvar.notfirstupdateklineUi = True
                    except Exception as e:
                        print("dict_dataframe_kline_M1 No Key:" + repr(e))

                    try:
                        self.plt_kline.addItem(self.item)
                        count += 1
                    except Exception as e:
                        print("UpdateKlineUIFromFileB Error:" + repr(e))
                    # 横坐标刻度

                    xax = self.plt_kline.getAxis('bottom')  # 坐标轴x
                    xdict = dict(enumerate(globalvar.ticklist))
                    xax.setTicks([xdict.items()])
            except Exception as e:
                print("updateklineUi Error:" + repr(e))

    # 更新分时图
    def updatemarketUi(self, newdata):
        global data_market, count
        data_market.append(newdata)
        if len(data_market) > 1000:
            data_market.pop(0)
        self.curve_market.setData(np.hstack(data_market))
        count += 1

    # 更新实时资金曲线
    def updaterealtimecurveUi(self, newdata, TradingDay):
        global data_realtimecurve, count, lastTradingDay
        data_realtimecurve.append(newdata)
        if TradingDay != lastTradingDay:
            lastTradingDay = TradingDay
            data_realtimecurve.pop(0)
        else:
            self.curve_realtime.setData(np.hstack(data_realtimecurve))
        count += 1

    def fileTime(self, file):
        return [time.ctime(os.path.getatime(file)), time.ctime(os.path.getctime(file)),
                time.ctime(os.path.getmtime(file))]

    # 单线程由Python直接驱动策略, 支持文件类型：（1）.py
    def Function_delete_clicked(self, arg):
        button = self.MainWindow.sender()
        if button:
            row = self.table_strategy.indexAt(button.pos()).row()
            self.table_strategy.removeRow(row)

    # 扫描目录下策略文件
    def Function_ScanStrategy(self):
        if True:
            module_strategy.Function_ScanStrategy_SingleThreadPyManage()
        else:
            module_strategy.Function_ScanStrategy_MulitProcess()

    # 扫描合约组设置
    def Function_ScanInstrumentIDGroup(self):
        module_instrumentgroup.Function_ScanInstrumentIDGroup()

    def Function_ScanMDHistorylog(self):
        path = "logfile/md"
        ls = os.listdir(path)
        for i in ls:
            c_path = os.path.join(path, i)
            if os.path.isdir(c_path):
                print(c_path)
                self.ClearPath(c_path, ".txt")
            else:
                file = os.path.splitext(c_path)
                filename, type = file
                if type == ".txt":
                    if True:
                        row_cnt = self.table_historymd.rowCount()  # 返回当前行数（尾部）
                        self.table_historymd.insertRow(row_cnt)  # 尾部插入一行新行表格
                        column_cnt = self.table_historymd.columnCount()  # 返回当前列数
                        item = QTableWidgetItem(str(row_cnt + 1))
                        self.table_historymd.setItem(row_cnt, 0, item)
                        item = QTableWidgetItem(str(c_path))
                        self.table_historymd.setItem(row_cnt, 1, item)

    def Function_ScanTDHistorylog(self):
        path = "logfile/td"
        ls = os.listdir(path)
        for i in ls:
            c_path = os.path.join(path, i)
            if os.path.isdir(c_path):
                print(c_path)
                self.ClearPath(c_path, ".txt")
            else:
                file = os.path.splitext(c_path)
                filename, type = file
                if type == ".txt":
                    if True:
                        row_cnt = self.table_historytd.rowCount()  # 返回当前行数（尾部）
                        # print("列数：",row_cnt)
                        self.table_historytd.insertRow(row_cnt)  # 尾部插入一行新行表格
                        item = QTableWidgetItem(str(row_cnt + 1))
                        self.table_historytd.setItem(row_cnt, 0, item)
                        item = QTableWidgetItem(str(c_path))
                        self.table_historytd.setItem(row_cnt, 1, item)

    # 打开策略目录
    def Function_OpenStrategyPath(self):
        cur_dir = QDir.currentPath() + "/strategyfile"
        os.startfile(cur_dir)

    # 打开策略池
    def Function_OnStrategyPool(self):
        return
        dlg_talibperiod = module_dlg.DialogStrategyPool()
        screen = QDesktopWidget().screenGeometry()
        size = dlg_talibperiod.geometry()
        dlg_talibperiod.move((screen.width() - size.width()) / 2,
                             (screen.height() - size.height()) / 2)
        dlg_talibperiod.setWindowTitle('策略池')
        dlg_talibperiod.show()
        dlg_talibperiod.resize(600, 440)
        dlg_talibperiod.exec_()

    def center(self):
        # 获取屏幕坐标系
        screen = QDesktopWidget().screenGeometry()
        # 获取窗口坐标系
        size = self.geometry()
        newLeft = (screen.width() - size.width()) / 2
        newTop = (screen.height() - size.height()) / 2
        self.move(newLeft, newTop)

    # 由模板创建策略文件
    def Function_NewStrategyFile(self):
        ui_demo = module_dlg.DialogNewStrategy(1)
        ui_demo.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowStaysOnBottomHint | QtCore.Qt.WindowCloseButtonHint)
        screen = QDesktopWidget().screenGeometry()
        size = ui_demo.geometry()
        newLeft = (screen.width() - size.width()) / 2
        newTop = (screen.height() - size.height()) / 2
        ui_demo.move(newLeft, newTop)
        ui_demo.setWindowTitle('添加新策略')
        ui_demo.show()
        ui_demo.exec_()

    def Function_SelectAll(self):
        row_cnt = globalvar.ui.table_strategy.rowCount()  # 返回当前行数（尾部）
        for i in range(row_cnt):
            c_path = globalvar.ui.table_strategy.item(i, 1).text()
            module_strategy.dict_strategyrun[c_path] == 1
            globalvar.ui.table_strategy.setEditTriggers(QTableView.NoEditTriggers)
            str = globalvar.ui.table_strategy.item(i, 0).text()
            item = QTableWidgetItem(str)
            item.setCheckState(QtCore.Qt.Checked)
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            globalvar.ui.table_strategy.setItem(i, 0, item)

    def Function_SelectNone(self):
        row_cnt = globalvar.ui.table_strategy.rowCount()  # 返回当前行数（尾部）
        for i in range(row_cnt):
            c_path = globalvar.ui.table_strategy.item(i, 1).text()
            module_strategy.dict_strategyrun[c_path] == 0
            globalvar.ui.table_strategy.setEditTriggers(QTableView.NoEditTriggers)
            str = globalvar.ui.table_strategy.item(i, 0).text()
            item = QTableWidgetItem(str)
            item.setCheckState(QtCore.Qt.Unchecked)
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            globalvar.ui.table_strategy.setItem(i, 0, item)

    # 打开回测报告目录
    def Function_OpenBackTestingPath(self):
        cur_dir = QDir.currentPath() + "/backtesting"
        os.startfile(cur_dir)

    # 清空今日行情日志
    def Function_ClearTodayMdLog(self):
        self.list_listmdlog.clear()

    # 清空今日交易日志
    def Function_ClearTodayTdLog(self):
        self.list_listtdlog.clear()

    # 打开算法交易目录
    def Function_OpenAlgorithmicTradingPath(self):
        cur_dir = QDir.currentPath() + "/AlgorithmicTrading"
        os.startfile(cur_dir)

    # 扫描交易历史日志
    def Function_ScanTdLog(self):
        path = "log"
        ls = os.listdir(path)
        for i in ls:
            c_path = os.path.join(path, i)
            if os.path.isdir(c_path):
                print(c_path)
                self.ClearPath(c_path, ".txt")
            else:
                file = os.path.splitext(c_path)
                filename, type = file
                if type == ".py" or type == ".pyd" or type == ".pyc":
                    print("find log file:", c_path)

    # 扫描行情历史日志
    def Function_ScanMdLog(self):
        path = "log"
        ls = os.listdir(path)
        for i in ls:
            c_path = os.path.join(path, i)
            if os.path.isdir(c_path):
                print(c_path)
                self.ClearPath(c_path, ".txt")
            else:
                file = os.path.splitext(c_path)
                filename, type = file
                if type == ".py" or type == ".pyd" or type == ".pyc":
                    print("find log file:", c_path)
                    # item = QtWidgets.table_strategy()
                    # self.table_strategy.setVerticalHeaderItem(1, item)

    def explainlog(self, str):
        _translate = QtCore.QCoreApplication.translate
        item = QtWidgets.QListWidgetItem()
        self.list_explain.addItem(item)
        item = self.list_explain.item(self.list_explain.count() - 1)
        item.setText(_translate("MainWindow", str))

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        # 交易信息
        self.groupBox.setTitle(_translate("MainWindow", ""))
        self.toolBox1.setItemText(self.toolBox1.indexOf(self.page_order), _translate("MainWindow", "委托"))
        self.toolBox1.setItemText(self.toolBox1.indexOf(self.page_trade), _translate("MainWindow", "交易"))
        self.toolBox1.setItemText(self.toolBox1.indexOf(self.page_instrument), _translate("MainWindow", "挂单(功能待升级)"))
        self.toolBox1.setItemText(self.toolBox1.indexOf(self.page_position), _translate("MainWindow", "持仓"))

        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_strategy), _translate("MainWindow", "策略池"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_instrumentgroup), _translate("MainWindow", "合约组"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_account), _translate("MainWindow", "账号"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_plus), _translate("MainWindow", "增值服务"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_algorithmtrading),
                                    _translate("MainWindow", "算法交易"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_instrument), _translate("MainWindow", "合约参数"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_marketdata), _translate("MainWindow", "Tick"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_listtdlog), _translate("MainWindow", "交易日志"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_listmdlog), _translate("MainWindow", "行情日志"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_historytd), _translate("MainWindow", "历史交易"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_historymd), _translate("MainWindow", "历史行情"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_backtestdata), _translate("MainWindow", "回测数据"))
        # self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_report), _translate("MainWindow", "回测报告"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_result), _translate("MainWindow", "回测报告"))
        self.tabWidget_2.setTabText(self.tabWidget_2.indexOf(self.tab_faq), _translate("MainWindow", "FAQ"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "功能区"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "交易"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "版本说明"))
        self.explainlog("本版本免费开源")
        self.toolButton.setText(_translate("MainWindow", "..."))
        self.menuMenu_nav1.setTitle(_translate("MainWindow", "&底层Dll日志"))
        self.menuMenu_nav2.setTitle(_translate("MainWindow", "&策略管理器"))
        self.menuMenu_nav3.setTitle(_translate("MainWindow", "&K线数据来源"))
        self.menuSubmenu_2.setTitle(_translate("MainWindow", "&Submenu 2"))
        self.dockWidget1.setWindowTitle(_translate("MainWindow", "实时行情和资金曲线(根据Tick实时生成K线)"))
        self.dockWidget1.setFeatures(QDockWidget.NoDockWidgetFeatures)
        self.comboBox_kline.setItemText(0, _translate("MainWindow", "K线周期: M1"))
        self.comboBox_kline.setItemText(1, _translate("MainWindow", "K线周期: M3"))
        self.comboBox_kline.setItemText(2, _translate("MainWindow", "K线周期: M5"))
        self.comboBox_kline.setItemText(3, _translate("MainWindow", "K线周期: M10"))
        self.comboBox_kline.setItemText(4, _translate("MainWindow", "K线周期: M15"))
        self.comboBox_kline.setItemText(5, _translate("MainWindow", "K线周期: M30"))
        self.comboBox_kline.setItemText(6, _translate("MainWindow", "K线周期: M60"))
        self.comboBox_kline.setItemText(7, _translate("MainWindow", "K线周期: D1"))
        self.comboBox_exchange.setItemText(0, _translate("MainWindow", "ALL,全部交易所"))
        self.comboBox_exchange.setItemText(1, _translate("MainWindow", "SHFE,上期所"))
        self.comboBox_exchange.setItemText(2, _translate("MainWindow", "DCE,大商所"))
        self.comboBox_exchange.setItemText(3, _translate("MainWindow", "CZCE,郑商所"))
        self.comboBox_exchange.setItemText(4, _translate("MainWindow", "CFFEX,中金所"))
        self.comboBox_exchange.setItemText(5, _translate("MainWindow", "INE,能源所"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
        self.Navgiate1.setText(_translate("MainWindow", "&VNPY官网"))
        self.Navgiate2.setText(_translate("MainWindow", "&VNTrader官网"))
        self.Navgiate3.setText(_translate("MainWindow", "&VNPY知乎"))
        self.Navgiate4.setText(_translate("MainWindow", "&知乎视频"))
        self.Navgiate5.setText(_translate("MainWindow", "&期货低佣金开户"))
        self.Navgiate6.setText(_translate("MainWindow", "&量化资源列表"))
        self.Navgiate2.setToolTip(_translate("MainWindow", "submenu"))
        self.Navgiate1_C.setText(_translate("MainWindow", "一键平仓"))
        self.Button_OpenDll.setText(_translate("MainWindow", "&开启DLL数据显示"))
        self.Button_CloseDll.setText(_translate("MainWindow", "&关闭DLL数据显示"))
        self.Button_StrategyManage_SingleThread.setText(_translate("MainWindow", "&Python单线程管理(仅支持.py策略文件类型)"))
        self.Button_StrategyManage_MulitProcess.setText(
            _translate("MainWindow", "&C++多进程管理（支持.py和.dll策略文件类型）（暂不支持，等待更新）"))
        self.Button_KlineSource_RealTimeTick.setText(_translate("MainWindow", "&实时TICK生成K线"))
        self.Button_KlineSource_ServerToday.setText(_translate("MainWindow", "&实时TICK生成K线 + 从服务器补齐1日K线"))
        self.Button_KlineSource_ServerMultiday.setText(
            _translate("MainWindow", "&实时TICK生成K线 + 从服务器补齐多日K线（增值服务Plus会员激活）"))
        self.Navgiate1.triggered.connect(self.Function_OpenUrl_VNPY)
        self.Navgiate2.triggered.connect(self.Function_OpenUrl_VNTRADER)
        self.Navgiate3.triggered.connect(self.Function_OpenUrl_ZHIHU)
        self.Navgiate4.triggered.connect(self.Function_OpenUrl_ZHIHUVIDEO)
        self.Navgiate5.triggered.connect(self.Function_OpenUrl_KAIHU)
        self.Navgiate6.triggered.connect(self.Function_OpenUrl_COOLQUANT)
        self.Button_OpenDll.triggered.connect(self.Function_OpenDllLog)
        self.Button_CloseDll.triggered.connect(self.Function_CloseDllLog)
        self.Button_StrategyManage_SingleThread.triggered.connect(self.Function_EnableStrategyManage_SingleThread)
        self.Button_StrategyManage_MulitProcess.triggered.connect(self.Function_EnableStrategyManage_MulitProcess)
        self.Button_KlineSource_RealTimeTick.triggered.connect(self.Function_KlineSource_RealTimeTick)
        self.Button_KlineSource_ServerToday.triggered.connect(self.Function_KlineSource_ServerToday)
        self.Button_KlineSource_ServerMultiday.triggered.connect(self.Function_KlineSource_ServerMultiday)
        self.Button_Start.clicked.connect(self.OnStart)
        self.Button_Stop.clicked.connect(self.OnStop)
        # 策略说明按钮
        self.Button_StrategyInstructions.clicked.connect(self.Function_StrategyInstructions)
        self.Button_StrategyFunction.clicked.connect(self.Function_StrategyInstructions)
        # 添加合约组
        self.Button_AddInstrumentGroup.clicked.connect(self.Function_AddInstrumentGroup)
        # 关于合约组说明
        self.Button_AboutInstrumentGroup.clicked.connect(self.Function_AboutInstrumentGroup)
        # 添加投资者账户按钮
        self.Button_AddInvestor.clicked.connect(self.Function_AddInvestor)
        # 修改投资者账户按钮
        self.Button_ModifyInvestor.clicked.connect(self.Function_ModifyInvestor)
        # 注册SIMNOW账户
        self.Button_Simnow.clicked.connect(self.Function_OpenUrl_SIMNOW)
        # 开立实盘账户（低佣金开户，A级期货公司）
        self.Button_Kaihu.clicked.connect(self.Function_OpenUrl_KAIHU)
        # Plus会员说明
        self.Button_Plus.clicked.connect(self.Function_OpenUrl_Plus)
        # VNPY社区
        self.Button_Community.clicked.connect(self.Function_OpenUrl_Community)
        # 绑定期货账号
        self.Button_BandPlus.clicked.connect(self.Function_OpenUrl_BandPlus)
        # 购买Plus
        self.Button_Buyplus.clicked.connect(self.Function_OpenUrl_Buyplus)
        self.Button_SetServiceUser.clicked.connect(self.Function_OpenUrl_VNPY)
        self.Button_BuyService.clicked.connect(self.Function_OpenUrl_VNPY)

        self.Button_AddStrategy.clicked.connect(self.Function_ScanStrategy)
        self.Button_OpenStrategyPath.clicked.connect(self.Function_OpenStrategyPath)
        self.Button_StrategyPool.clicked.connect(self.Function_OnStrategyPool)
        self.Button_NewStrategyFile.clicked.connect(self.Function_NewStrategyFile)
        self.Button_SelectAll.clicked.connect(self.Function_SelectAll)
        self.Button_SelectNone.clicked.connect(self.Function_SelectNone)

        self.Button_OpenAlgorithmicTradingPath.clicked.connect(self.Function_OpenAlgorithmicTradingPath)
        self.Button_OpenBackTestingPath.clicked.connect(self.Function_OpenBackTestingPath)
        self.Button_ClearTodayMdLog.clicked.connect(self.Function_ClearTodayMdLog)
        self.Button_ClearTodayTdLog.clicked.connect(self.Function_ClearTodayTdLog)
        self.Button_FaqDevelopmentEnvironment.clicked.connect(self.Function_FaqDevelopmentEnvironment)
        self.Button_FaqKaihu.clicked.connect(self.Function_FaqKAIHU)
        self.Function_ScanStrategy()
        self.Function_ScanInstrumentIDGroup()
        self.Function_ScanTDHistorylog()
        self.Function_ScanMDHistorylog()
        module_backtest.Function_ReadDataList(globalvar.ui.table_backtestdata, False)

    # 编辑合约组里的合约窗口
    class DialogEditInstrumentID(QtWidgets.QDialog):
        def __init__(self, filename):
            super().__init__()
            self.filename = filename
            self.InitUI()

        def closeEvent(self, event):
            globalvar.DialogSetInstrumentState = False

        readfinish = False
        # 保存已经生效的合约
        dict_EnableInstrumentID = {}

        # 读取股票图表访问历史列表
        def ReadInstrumentIDGroup(self):
            returnvalue = False
            with open(self.filename, 'r') as f:
                for line in f:
                    enablelist = line.strip('\n').split(',')
                    if len(enablelist) > 0:
                        for j in range(len(enablelist)):
                            _translate = QtCore.QCoreApplication.translate
                            item = QtWidgets.QListWidgetItem()
                            self.list_instrumentidgroupselect.addItem(item)
                            item = self.list_instrumentidgroupselect.item(
                                self.list_instrumentidgroupselect.count() - 1)
                            item.setText(_translate("MainWindow", enablelist[j]))
                            self.dict_EnableInstrumentID[enablelist[j]] = True
                        returnvalue = True
                    else:
                        returnvalue = False
                self.readfinish = True
            return returnvalue

        # 选入合约（更新显示，更新文件，更新内存变量）
        def AddAndUpdateInstrumentIDGroupFile(self, InstrumentID):
            _translate = QtCore.QCoreApplication.translate
            item = QtWidgets.QListWidgetItem()
            self.list_instrumentidgroupselect.addItem(item)
            item = self.list_instrumentidgroupselect.item(self.list_instrumentidgroupselect.count() - 1)
            item.setText(_translate("MainWindow", InstrumentID))
            self.dict_EnableInstrumentID[InstrumentID] = True
            with open(self.filename, 'r') as f:
                for line in f:
                    line = line + ',' + InstrumentID
                    with open(self.filename, "w") as f:
                        f.write(line)
                    return

        # 删除合约（更新显示，更新文件，更新内存变量）
        def RemoveAndUpdateInstrumentIDGroupFile(self, InstrumentID):
            '''
            tconut=self.list_instrumentidgroupselect.count()
            if tconut>0:
                for index in range(tconut):
                    item = self.list_instrumentidgroupselect.item(index)
                    if item.text() == InstrumentID:
                        #self.list_instrumentidgroupselect.tackItem(item)
                        self.list_instrumentidgroupselect.removeItemWidget(item)
                        del item
                        break
            '''
            # self.dict_EnableInstrumentID[InstrumentID] = False
            with open(self.filename, 'r') as f:
                for line in f:
                    line = line.replace(InstrumentID, '')
                    line = line.replace(',,', ',')
                    print(line)
                    if line[-1] == ',':
                        line = line[:-1]
                    print(line)
                    if line[0] == ',':
                        line = line[1:]
                    print(line)
                    with open(self.filename, "w") as f:
                        f.write(line)
                    continue
            self.dict_EnableInstrumentID.clear()
            self.list_instrumentidgroupselect.clear()
            self.ReadInstrumentIDGroup()

        # checkbox改变事件，选入合约或删除合约
        def OnCellChanged(self, row, column):
            LastStateRole = QtCore.Qt.UserRole
            if self.readfinish:
                if column != 3:
                    return
                item = self.tableWidget.item(row, column)
                lastState = item.data(LastStateRole)
                currentState = item.checkState()
                if currentState != lastState:
                    # print('changed(group)')
                    AddInstrumentID = globalvar.ui.table_instrument.item(row, 2).text()
                    if currentState == QtCore.Qt.Checked:
                        # print('checked(group): '+AddInstrumentID)
                        self.AddAndUpdateInstrumentIDGroupFile(AddInstrumentID)
                    else:
                        self.RemoveAndUpdateInstrumentIDGroupFile(AddInstrumentID)
                        # print("unchecked(group)")
                    item.setData(LastStateRole, currentState)

        def InitUI(self):
            self.setWindowIcon(QIcon(r'setinstrument.ico'))  # 设置窗口图标
            self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
            self.tableWidget = QTableWidget()
            self.layout = QHBoxLayout()
            self.btn_left = QPushButton('', self)
            self.btn_right = QPushButton('', self)
            row_cnt = globalvar.ui.table_instrument.rowCount()  # 返回当前行数（尾部）
            self.tableWidget.setObjectName("setinstrument")
            self.tableWidget.verticalHeader().setVisible(True)  # 隐藏垂直表头
            self.tableWidget.horizontalHeader().setVisible(True)  # 隐藏水平表头
            self.tableWidget.setEditTriggers(QTableView.NoEditTriggers)
            self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
            self.tableWidget.setColumnCount(4)
            self.tableWidget.setRowCount(row_cnt)
            self.tableWidget.setHorizontalHeaderLabels(
                ['合约', '合约代码', '交易所', '加入'])  # 设置表头文字
            self.tableWidget.setSortingEnabled(True)  # 设置表头可以自动排序
            self.tab_tableWidget = QtWidgets.QWidget()
            self.tab_tableWidget.setObjectName("tab_tableWidget")
            self.list_instrumentidgroupselect = QtWidgets.QListWidget(self.tab_tableWidget)
            self.list_instrumentidgroupselect.setObjectName("list_instrumentidgroupselect")
            _translate = QtCore.QCoreApplication.translate
            __sortingEnabled = self.list_instrumentidgroupselect.isSortingEnabled()
            self.list_instrumentidgroupselect.setSortingEnabled(False)
            self.list_instrumentidgroupselect.setSortingEnabled(__sortingEnabled)
            self.layout = QtWidgets.QGridLayout(self.tab_tableWidget)
            self.layout.setContentsMargins(0, 0, 0, 0)
            self.layout.setObjectName("gridLayout_strategy")
            # self.tableWidget.setCellWidget(0, 8, Trade_BacktestingBtn)
            self.layout.addWidget(self.tableWidget, 0, 0, 1, 4)
            self.layout.addWidget(self.list_instrumentidgroupselect, 0, 4, 1, 3)
            self.layout.addWidget(self.btn_left, 2, 0, 4, 4)
            self.layout.addWidget(self.btn_right, 2, 4, 4, 3)
            # self.list_instrumentidgroupselect.clear()
            # self.tableWidget.doubleClicked.connect(self.sync_table_double_clicked)
            # 读取已经设置的合约列表，在对话框右边视图显示
            self.ReadInstrumentIDGroup()
            # indexes = globalvar.ui.table_instrumentcx.selectedIndexes()  # 获取表格对象中被选中的数据索引列表
            for i in range(row_cnt):
                for j in range(4 - 1):
                    strs = globalvar.ui.table_instrument.item(i, j + 1).text()
                    item = QTableWidgetItem(strs)
                    self.tableWidget.setItem(i, j, item)
                item = QTableWidgetItem('选择')
                try:
                    if self.dict_EnableInstrumentID[globalvar.ui.table_instrument.item(i, 2).text()]:
                        item.setCheckState(QtCore.Qt.Checked)
                    else:
                        item.setCheckState(QtCore.Qt.Unchecked)
                except Exception as e:
                    item.setCheckState(QtCore.Qt.Unchecked)
                self.tableWidget.setItem(i, 3, item)
            self.tableWidget.cellChanged.connect(self.OnCellChanged)
            self.setLayout(self.layout)
            # 参数个数
            labelpar = []

            def function_item_clicked(self, QTableWidgetItem):
                check_state = QTableWidgetItem.checkState()
                row = QTableWidgetItem.row()
                if check_state == QtCore.Qt.Checked:
                    if row not in self.delete_row:
                        self.delete_row.append(row)
                elif check_state == QtCore.Qt.Unchecked:
                    if row in self.delete_row:
                        self.delete_row.remove(row)

            try:
                for i in range(len(globalvar.dict_talibcondition[self.strategyname])):
                    # print('lid: ' + str(globalvar.dict_talibcondition[self.strategyname][i]))
                    item = QTableWidgetItem(' 启用该条件')
                    if globalvar.dict_talibcondition[self.strategyname][i][1] == 1:
                        item.setCheckState(QtCore.Qt.Checked)
                    else:
                        item.setCheckState(QtCore.Qt.Checked)
                    # item.connect(self.table_algorithmtrading, QtCore.SIGNAL("itemClicked(QTableWidgetItem*)"), self.function_item_clicked)
                    self.tableWidget.setItem(i, 0, item)
                    item = QTableWidgetItem(globalvar.dict_talibcondition[self.strategyname][i][2])
                    self.tableWidget.setItem(i, 1, item)
                    item = QTableWidgetItem(globalvar.dict_talibcondition[self.strategyname][i][3])
                    self.tableWidget.setItem(i, 2, item)
                    item = QTableWidgetItem(globalvar.dict_talibcondition[self.strategyname][i][4])
                    self.tableWidget.setItem(i, 3, item)
            except Exception as e:
                print("DialogEditInstrumentID InitUI Error:" + repr(e))

            try:
                parnum = 0
                for i in range(len(module_talib.dict_talibparameter[self.strategyname][3][0])):
                    tempparlabel2 = QLabel(self)
                    EditPar = QLineEdit(self)
                    EditPar2 = QLineEdit(self)
                    tempparlabel2.setText(str(module_talib.dict_talibparameter[self.strategyname][3][0][0]))
                    tempparlabel2.move(60, 230 + parnum * 40)
                    EditPar.setText('>' + str(module_talib.dict_talibparameter[self.strategyname][3][0][1]))
                    EditPar.move(200, 230 + parnum * 40)
                    EditPar.resize(120, 30)
                    EditPar2.setText('趋势条件')
                    EditPar2.move(400, 230 + parnum * 40)
                    EditPar2.resize(120, 30)
            except Exception as e:
                print("talib.csv格式错误 Error:" + repr(e))
                return

            self.btn_ok = QPushButton('添加指标条件', self)
            self.btn_ok.move(300, 480)
            self.btn_ok.resize(300, 50)
            Edit2 = QLineEdit(self)
            Edit2.setText('（该指标条件可用于组合成策略）')
            Edit2.move(360, 550)
            Edit2.resize(180, 30)
            self.setGeometry(500, 600, 420, 450)
            self.show()
            try:
                global config
                config = configparser.ConfigParser()
                # -read读取ini文件
                config.read('vnctptd.ini', encoding='utf-8')
                brokeid = config.get('setting', 'brokeid')
                investor = config.get('setting', 'investor')
                password = config.get('setting', 'password')
                appid = config.get('setting', 'appid')
                userproductinfo = config.get('setting', 'userproductinfo')
                authcode = config.get('setting', 'authcode')
                address1 = config.get('setting', 'address1')
                address2 = config.get('setting', 'address2')
                address3 = config.get('setting', 'address3')
                print('read %s %s %s' % (investor, password, appid))
                self.Edit_brokerid.setText(brokeid)
                self.Edit_investor.setText(investor)
                self.Edit_password.setText(password)
                self.Edit_APPID.setText(appid)
                self.Edit_authcode.setText(authcode)
                self.Edit_auserproductinfo.setText(userproductinfo)
                self.Edit_addr1.setText(address1)
                self.Edit_addr2.setText(address2)
                self.Edit_addr3.setText(address3)
            except Exception as e:
                print("initUI Error:" + repr(e))

        def showDialog(self):
            text, ok = QInputDialog.getText(self, '选择期货公司自动确认brokeid和ip',
                                            '选择期货公司:')
            if ok:
                self.le.setText(str(text))
